/*
 * @(#)GsMngManager.java
 * 2011-8-21 下午10:13:50
 *
 * Copyright (c) 2018-2028, HangZhou QiYun InfoTech Co.,Ltd. .
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.qyxx.platform.gsmng.common.service;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.qyxx.jwp.bean.*;
import com.qyxx.jwp.datasource.QuerySql;
import com.qyxx.jwp.datasource.TableEntity;
import com.qyxx.jwp.datasource.TeAttr;
import com.qyxx.platform.common.orm.Page;
import com.qyxx.platform.common.orm.PropertyFilter;
import com.qyxx.platform.common.utils.DynamicSqlUtils;
import com.qyxx.platform.common.utils.doc.WordUtils;
import com.qyxx.platform.common.utils.encode.JsonBinder;
import com.qyxx.platform.common.utils.jxls.JxlsUtils;
import com.qyxx.platform.common.utils.spring.SpringContextHolder;
import com.qyxx.platform.gsc.cache.SqlCache;
import com.qyxx.platform.gsc.cache.TableEntityCache;
import com.qyxx.platform.gsc.utils.GsDataType;
import com.qyxx.platform.gsc.utils.SystemParam;
import com.qyxx.platform.gsmng.common.dao.GsMngDao;
import com.qyxx.platform.sysmng.accountmng.entity.Organization;
import com.qyxx.platform.sysmng.accountmng.entity.User;
import com.qyxx.platform.sysmng.accountmng.service.AccountManager;
import com.qyxx.platform.sysmng.exception.GsException;
import com.qyxx.platform.sysmng.notice.dao.NoticeDao;
import com.qyxx.platform.sysmng.notice.dao.NoticeToUserDao;
import com.qyxx.platform.sysmng.notice.entity.CommonType;
import com.qyxx.platform.sysmng.notice.entity.Notice;
import com.qyxx.platform.sysmng.notice.entity.NoticeToUser;
import com.qyxx.platform.sysmng.notice.service.CommonTypeManager;
import com.qyxx.platform.sysmng.notice.service.NoticeManager;
import com.qyxx.platform.sysmng.utils.Constants;
import net.sf.jxls.exception.ParsePropertyException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.hibernate.Transaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 业务管理通用Service
 * 
 * @author gxj
 * @version 1.0
 * @since 1.6 2011-8-21 下午10:13:50
 */
@Service
@Scope("prototype")
@Transactional
public class GsMngManager {

	public static final String INSERTED = "inserted";

	public static final String UPDATED = "updated";

	public static final String DELETED = "deleted";
	
	public static final String DATA = "data"; //子表数据
	
	public static final String SAVE_TYPE = "saveType"; //保存类型
	
	public static final String SAVE_TYPE_MODIFY = "saveModify";//保存修改的数据 
	
	public static final String BUSINESS_MESSAGE = "businessMessage";
	
	public static final String READ_NOTICE_TO_USER_ID = "readNoticeToUserId";//业务通知关联ID
	
	public static final String AUTO_ID_RULE = "autoIdRule";

	// 状态：初始化
	public static final String STATUS_INIT = "00";
	// 状态：草稿
	public static final String STATUS_DRAFT = "10";
	// 状态：审批中
	public static final String STATUS_APPROVAL = "20";
	// 状态：审批结束
	public static final String STATUS_FINISH = "31";
	// 状态：审批通过
	public static final String STATUS_PASS = "31";
	// 状态：审批不通过
	public static final String STATUS_NO_PASS  = "32";
	// 状态：审核通过
	public static final String STATUS_OK = "35";
	// 状态：作废
	public static final String STATUS_CANCEL = "40";
	// 主键
	public static final String ID = "id";
	// 乐观锁版本
	public static final String VERSION = "version";
	// 创建者
	public static final String CREATE_USER = "createUser";
	// 创建时间
	public static final String CREATE_TIME = "createTime";
	// 修改者
	public static final String LAST_UPDATE_USER = "lastUpdateUser";
	// 修改时间
	public static final String LAST_UPDATE_TIME = "lastUpdateTime";
	// 状态
	public static final String STATUS = "status";
	// 排序号
	public static final String SORT_ORDER_NO = "sortOrderNo";
	// 附件编号
	public static final String ATM_ID = "atmId";
	// 流程实例编号
	public static final String FLOW_INS_ID = "flowInsId";
	//作废原因
	public static final String CANCEL_REASON = "cancelReason";
	//关联主表ID
	public static final String MASTER_ID = "masterId";
	//实体名
	public static final String ENTITY_NAME = "entityName";
	//实体ID
	public static final String ENTITY_ID = "entityId";
	//库存系数
	public static final String STOCK_RATIO = "stockRatio";
	//入库系数
	public static final Long STOCK_RATIO_IN = 1L;
	//出库系数
	public static final Long STOCK_RATIO_OUT = -1L;
	//组织父节点参数
	public static final String PARENT_ORG_CODES = "parentOrgCodes";
	//当前组织节点参数
	public static final String ORG_CODE = "orgCode";
	
	public static final String  TASK_ID = "taskId";
	
	public static final String  TASK_NAME  = "taskName";
	
	//树形结构父节点编号
	public static final String PARENTCODE = "autoParentCode";
	//树形展示父节点编号
	public static final String PARENTID = "_parentId";
	//导入异常信息key
	public static final String IMPORT_MSG = "_importMsg_";
	//导入异常原因描述
	public static final String IMPORT_MSG_CAPTION = "导入异常原因";
	//text属性
	public static final String TEXT = "text";
	
	
	private static final String UNIQUE_TASKS = "select a.ID_,a.NAME_ " +
			"from ACT_RU_TASK a " +
			"where a.PROC_INST_ID_ = ? and ( a.ASSIGNEE_ = ? or (a.ASSIGNEE_ is null and exists(select b.ID_ from ACT_RU_IDENTITYLINK b " +
			"where b.TASK_ID_ = a.ID_ and b.USER_ID_ = ? ))) order by a.CREATE_TIME_ desc";

	//异步服务线程池
	private ExecutorService asyncServicePool =  Executors.newFixedThreadPool(20);

	protected String entityName;
	// 用户ID
	protected User user;

	// 主实体Dao
	private GsMngDao gsMngDao;
	
	private static Logger logger = LoggerFactory
			.getLogger(GsMngManager.class);

	private NoticeDao noticeDao;
	
	private NoticeToUserDao noticeToUserDao;
	
	private NoticeManager noticeManager;
	
	private AccountManager accountManager;
	
	private JsonBinder jsonBinder = JsonBinder.getAlwaysMapper();
	
	private SystemParam systemParam = SpringContextHolder.getBean("systemParam");
	
	private CommonTypeManager commonTypeManager;
	
	@Autowired
	public void setNoticeToUserDao(NoticeToUserDao noticeToUserDao) {
		this.noticeToUserDao = noticeToUserDao;
	}

	@Autowired
	public void setNoticeDao(NoticeDao noticeDao) {
		this.noticeDao = noticeDao;
	}
	
	/**
	 * @param noticeManager
	 */
	@Autowired
	public void setNoticeManager(NoticeManager noticeManager) {
		this.noticeManager = noticeManager;
	}

	/**
	 * @param gsMngDao
	 */
	@Autowired
	public void setGsMngDao(GsMngDao gsMngDao) {
		this.gsMngDao = gsMngDao;
	}
	
	/**
	 * @param accountManager
	 */
	@Autowired
	public void setAccountManager(AccountManager accountManager) {
		this.accountManager = accountManager;
	}
	
	/**
	 * @param commonTypeManager
	 */
	@Autowired
	public void setCommonTypeManager(CommonTypeManager commonTypeManager) {
		this.commonTypeManager = commonTypeManager;
	}

	/**
	 * @return entityName
	 */
	public String getEntityName() {
		return entityName;
	}

	/**
	 * 设置实体名称
	 * 
	 * @param entityName
	 */
	public void setEntityName(String entityName) {
		this.entityName = entityName;
		gsMngDao.setEntityName(entityName);
	}

	/**
	 * @param user
	 *            the user to set
	 */
	public void setUser(User user) {
		this.user = user;
	}

	/**
	 * 将source中的属性copy至target，覆盖原值
	 * 
	 * @param target
	 * @param source
	 */
	public void copyMap(Map<String, Object> target,
			Map<String, Object> source) {
		if (null != source && null != target) {
			for (Map.Entry<String, Object> en : source.entrySet()) {
				target.put(en.getKey(), en.getValue());
			}
		}
	}
	
	/**
	 * 批量保存实体对象
	 * 
	 * @param entityList
	 */
	public List<Object> saveEntityList(List<Map<String, Object>> entityList, String idAttr, Boolean isUpdate) {
		List<Object> resultList = Lists.newArrayList();
		if(null!=entityList && !entityList.isEmpty()) {
			for(Map<String, Object> entity : entityList) {
				Object id = saveEntityByIdAttr(entity, idAttr, isUpdate);
				if(null!=id) {
					resultList.add(id);
				}
			}
		}
		return resultList;
	}
	
	/**
	 * 根据IdAttr属性值保存实体对象
	 * 
	 * @param entity
	 * @param idAttr
	 * @param isUpdate --是否更新
	 */
	public Object saveEntityByIdAttr(Map<String, Object> entity, String idAttr, Boolean isUpdate) {
		Map<String, Object> subMap = new HashMap<String, Object>();
		TableEntity te = TableEntityCache.getInstance().get(
				this.entityName);
		List<TableEntity> subTiList = te.getSubEntitys();
		if (null != subTiList && !subTiList.isEmpty()) {
			for (TableEntity subEntity : subTiList) {
				String subEntityName = subEntity.getEntityName();
				Object subObj = entity.remove(subEntity
						.getRefSubEntityName());
				subMap.put(subEntityName, subObj);
			}
		}
		//同步属性列表
		List<TeAttr> syncTaList = new ArrayList<TeAttr>();
		//拆分属性列表
		List<TeAttr> splitTaList = new ArrayList<TeAttr>();
		// 转换类型
		Map<String, Map<String, Object>> mainReferEntity = prepareMapObj(entity, te, syncTaList, splitTaList);
		Object id = entity.get(idAttr);
		Boolean isModify = false;
		List<Map<String, Object>> loadMapList = gsMngDao.findBy(idAttr, id);
		if (null != loadMapList && !loadMapList.isEmpty()) {
			isModify = true;
			if(isUpdate) {
				// 修改主表记录
				Map<String, Object> loadMap = loadMapList.get(0);
				copyMap(loadMap, entity);
				entity = loadMap;
			} else {
				return id;
			}
		} else {
			//后台生成自动编号
			this.setAutoIdColumn(entity, this.entityName);
			// 新增主表记录
			gsMngDao.save(entity);
		}
		for (Map.Entry<String, Object> ens : subMap.entrySet()) {
			String subEntityName = ens.getKey();
			Object subObj = ens.getValue();
			TableEntity subTe = TableEntityCache
					.getInstance().get(subEntityName);
			if (null != subObj && subObj instanceof Map) {
				if(isModify) {
					//修改主表数据下，先删除子表数据，再重新添加
					gsMngDao.deleteSubEntity(subEntityName, subTe.getRefEntityName(), (Long)entity.get(ID));
				}
				Map<String, Object> obj = (Map<String, Object>) subObj;
				for (Map.Entry<String, Object> en : obj.entrySet()) {
					if (INSERTED.equals(en.getKey())
							|| UPDATED.equals(en.getKey())) {
						if (null != en.getValue()
								&& en.getValue() instanceof List) {
							Long i = 1L;
							for (Object o : (List<Object>) en
									.getValue()) {
								if (o instanceof Map) {
									Map<String, Object> to = (Map<String, Object>) o;
									//子表拆分属性
									List<TeAttr> subSplitTaList = new ArrayList<TeAttr>();
									// 转换类型
									Map<String, Map<String, Object>> subReferEntity = prepareMapObj(to, subTe, null, subSplitTaList);
									to.put(subTe.getRefEntityName(),
											entity);
									//后台生成自动编号
									this.setAutoIdColumn(to, subEntityName);
									// 加入排序号
									to.put(SORT_ORDER_NO, i++);
									gsMngDao.save(to,
												subEntityName);
								}
							}
						}
					}
				}
			}
		}
		return null;
	}
	
	/**
	 * 判断字段是否存在
	 * 
	 * @param entity
	 */
	public boolean disAttr(Object id) {
		List<Map<String, Object>> loadMapList = gsMngDao.findBy("dingdanhao", id);
		if(loadMapList.isEmpty()) {
			return true;
		}
		return false;
	}
	
	/**
	 * 通过订单号与修改时间判断字段是否存在
	 * 
	 * @param entity
	 */
	public boolean disAttr(Object tid, Object jdp_modified) {
		List<Map<String, Object>> loadMapList = gsMngDao.findBy("dingdanhao", tid);
		if(!loadMapList.isEmpty()) {
			for(Map<String, Object> loadMap : loadMapList) {
				if(jdp_modified.equals(loadMap.get("xiugaishijian"))) {
					return false;
				}
			}
		}
		return true;
	}
	
	/**
	 * 根据订单号返回行数据
	 * 
	 * @param entity
	 */
	public List<Map<String, Object>> findBy(Object tid) {
		return gsMngDao.findBy("dingdanhao", tid);
	}

	/**
	 * 保存实体
	 * 
	 * @param entity
	 */
	@SuppressWarnings("unchecked")
	public void saveEntity(Map<String, Object> entity,Map<String, Object> entitySend) {
		Map<String, Object> subMap = new HashMap<String, Object>();
		TableEntity te = TableEntityCache.getInstance().get(
				this.entityName);
		List<TableEntity> subTiList = te.getSubEntitys();
		if (null != subTiList && !subTiList.isEmpty()) {
			for (TableEntity subEntity : subTiList) {
				String subEntityName = subEntity.getEntityName();
				Object subObj = entity.remove(subEntity
						.getRefSubEntityName());
				subMap.put(subEntityName, subObj);
			}
		}
		//同步属性列表
		List<TeAttr> syncTaList = new ArrayList<TeAttr>();
		//拆分属性列表
		List<TeAttr> splitTaList = new ArrayList<TeAttr>();
		// 转换类型
		Map<String, Map<String, Object>> mainReferEntity = prepareMapObj(entity, te, syncTaList, splitTaList);
		//自定义编号生成
		/*if(null!=entitySend) {
			this.setAutoIdColumn(entity, entitySend.get(AUTO_ID_RULE));
		}*/
		//后台生成自动编号
		this.setAutoIdColumn(entity, this.entityName);
		Long id = (Long) entity.get(ID);
		if (null != id) {
			// 修改
			Map<String, Object> loadMap = gsMngDao.get(id);
			Object dbVersion = loadMap.get(VERSION);
			Object pageVersion = entity.get(VERSION);
			if(dbVersion != null && pageVersion !=null && !dbVersion.equals(pageVersion)) {
				throw new GsException("数据已经被修改过，请取消后再进行修改保存操作！");
			}
			copyMap(loadMap, entity);
			entity = loadMap;
			//修改关联表数据
			saveReferEntity(te, mainReferEntity, this.entityName, id, false, splitTaList);
		} else {
			// 新增
			gsMngDao.save(entity);
			//新增关联表数据
			saveReferEntity(te, mainReferEntity, this.entityName, (Long)entity.get(ID), true, splitTaList);
		}
		for (Map.Entry<String, Object> ens : subMap.entrySet()) {
			String subEntityName = ens.getKey();
			Object subObj = ens.getValue();
			TableEntity subTe = TableEntityCache
					.getInstance().get(subEntityName);
			if (null != subObj && subObj instanceof Map) {
				Map<String, Object> obj = (Map<String, Object>) subObj;
				for (Map.Entry<String, Object> en : obj.entrySet()) {
					if (INSERTED.equals(en.getKey())
							|| UPDATED.equals(en.getKey())) {
						if (null != en.getValue()
								&& en.getValue() instanceof List) {
							Long i = 1L;
							for (Object o : (List<Object>) en
									.getValue()) {
								if (o instanceof Map) {
									Map<String, Object> to = (Map<String, Object>) o;
									//子表拆分属性
									List<TeAttr> subSplitTaList = new ArrayList<TeAttr>();
									// 转换类型
									Map<String, Map<String, Object>> subReferEntity = prepareMapObj(to, subTe, null, subSplitTaList);
									to.put(subTe.getRefEntityName(),
											entity);
									// 加入排序号
									to.put(SORT_ORDER_NO, i++);
									// 设置自动编号
									this.setAutoIdColumn(to, subEntityName);
									Long subId = (Long)to.get(ID);
									if (null == subId) {
										// 新增
										//to.remove(ID);
										gsMngDao.save(to,
												subEntityName);
										//新增关联表数据
										saveReferEntity(subTe, subReferEntity, subEntityName, (Long)to.get(ID), true, subSplitTaList);
									} else {
										// 修改
										Map<String, Object> loadMap = gsMngDao
												.get(subId,
														subEntityName);
										copyMap(loadMap, to);
										//修改关联表数据
										saveReferEntity(subTe, subReferEntity, subEntityName, subId, false, subSplitTaList);
									}
								}
							}
						}
					} else if (DELETED.equals(en.getKey())) {
						// 删除
						if (null != en.getValue()
								&& en.getValue() instanceof List) {
							for (Object o : (List<Object>) en
									.getValue()) {
								if (o instanceof Map) {
									Map<String, Object> to = (Map<String, Object>) o;
									Long subId = ((Number)to.get(ID)).longValue();
									//先删除关联表数据
									deleteReferEntity(subTe.getIsReferCommon(), subTe.getReferEntityNameList(), subEntityName, subId);
									gsMngDao.delete(subId, subEntityName);
								}
							}
						}
					}
				}
			}
		}
		//同步主、子表数据
		if(!syncTaList.isEmpty()) {
			syncDataBetweenEntitys(syncTaList, entity);
		}
		//发送消息
		if(entitySend!=null){
			this.sendMessage(entity, entitySend.get(BUSINESS_MESSAGE));
			this.autoReadNotice(entitySend.get(READ_NOTICE_TO_USER_ID));
		}
	}
	
	/**
	 * 自动阅读关联通知
	 * 
	 * @param ntuId
	 */
	private void autoReadNotice(Object ntuId) {
		if(ntuId != null) {
			Long noticeToUserId = Long.valueOf((String)ntuId);
			noticeManager.readNotice(noticeToUserId);
		}
	}
	
	/**
	 * 保存或修改关联表数据
	 * 
	 * @param te
	 * @param referEntity
	 * @param mainEntityName
	 * @param mainEntityId
	 * @param isNewAdd
	 * @param splitTaList -- 拆分属性列表
	 */
	private void saveReferEntity(TableEntity te, Map<String, Map<String, Object>> referEntity, 
			String mainEntityName, Long mainEntityId, Boolean isNewAdd, List<TeAttr> splitTaList) {
		if(te.getIsReferCommon()) {
			for(Map.Entry<String, Map<String, Object>> en : referEntity.entrySet()) {
				Map<String, Object> re = en.getValue();
				String referEntityName = en.getKey();
				String stockType = te.getStockType();
				if(isNewAdd) { //新增
					re.put(ENTITY_ID, mainEntityId);
					re.put(ENTITY_NAME, mainEntityName);
					if(Form.STOCK_TYPE_IN_OUT.equals(stockType)) {
						//出入库			
						Map<String, Object> re2 = splitOneToTwoObject(te, re, splitTaList);
						gsMngDao.save(re, referEntityName);
						gsMngDao.save(re2, referEntityName);
					} else {
						if(Form.STOCK_TYPE_IN.equals(stockType)) {
							//入库
							re.put(STOCK_RATIO, STOCK_RATIO_IN);
						} else if(Form.STOCK_TYPE_OUT.equals(stockType)) {
							//出库
							re.put(STOCK_RATIO, STOCK_RATIO_OUT);
						}
						gsMngDao.save(re, referEntityName);
					}
				} else { //修改
					if(Form.STOCK_TYPE_IN_OUT.equals(stockType)) {
						//出入库			
						Map<String, Object> re2 = splitOneToTwoObject(te, re, splitTaList);
						Map<String, Object> loadMapIn = gsMngDao.getReferEntity(referEntityName, mainEntityName, mainEntityId, STOCK_RATIO_IN);
						handleEmptyEntity(loadMapIn, mainEntityName, mainEntityId);
						
						Map<String, Object> loadMapOut = gsMngDao.getReferEntity(referEntityName, mainEntityName, mainEntityId, STOCK_RATIO_OUT);
						handleEmptyEntity(loadMapOut, mainEntityName, mainEntityId);
						if(Form.STOCK_TYPE_OUT.equals(te.getInOutVal())) {
							copyMap(loadMapIn, re2);
							copyMap(loadMapOut, re);
						} else {
							copyMap(loadMapOut, re2);
							copyMap(loadMapIn, re);
						}
						gsMngDao.save(loadMapOut, referEntityName);
						gsMngDao.save(loadMapIn, referEntityName);
					} else {
						if(Form.STOCK_TYPE_IN.equals(stockType)) {
							//入库
							re.put(STOCK_RATIO, STOCK_RATIO_IN);
						} else if(Form.STOCK_TYPE_OUT.equals(stockType)) {
							//出库
							re.put(STOCK_RATIO, STOCK_RATIO_OUT);
						}
						//根据实体名和实体ID获取关联对象
						Map<String, Object> loadMap = gsMngDao.getReferEntity(referEntityName, mainEntityName, mainEntityId);
						//处理空实体
						handleEmptyEntity(loadMap, mainEntityName, mainEntityId);
						copyMap(loadMap, re);
						gsMngDao.save(loadMap, referEntityName);
					}
				}
			}
		}
	}
	
	/**
	 * 保存子表数据
	 * 
	 * @param entity
	 */
	@SuppressWarnings("unchecked")
	public void saveSubEntity(Map<String, Object> dataMap) {
		String subEntityName = this.entityName;
		Long id = ((Number)dataMap.get(ID)).longValue();
		Object subObj = dataMap.get(DATA);
		String saveType = (String)dataMap.get(SAVE_TYPE);
		TableEntity subTe = TableEntityCache
				.getInstance().get(subEntityName);
		if (null != subObj && subObj instanceof Map) {
			Map<String, Object> entity = gsMngDao.get(id, subTe.getMasterEntityName()); //查询关联主表记录
			Map<String, Object> obj = (Map<String, Object>) subObj;
			for (Map.Entry<String, Object> en : obj.entrySet()) {
				if (INSERTED.equals(en.getKey())
						|| UPDATED.equals(en.getKey())) {
					if (null != en.getValue()
							&& en.getValue() instanceof List) {
						Long i = 1L;
						for (Object o : (List<Object>) en
								.getValue()) {
							if (o instanceof Map) {
								Map<String, Object> to = (Map<String, Object>) o;
								//子表拆分属性
								List<TeAttr> subSplitTaList = new ArrayList<TeAttr>();
								// 转换类型
								Map<String, Map<String, Object>> subReferEntity = prepareMapObj(to, subTe, null, subSplitTaList);
								to.put(subTe.getRefEntityName(),
										entity);
								// 设置自动编号
								this.setAutoIdColumn(to, subEntityName);
								if(!SAVE_TYPE_MODIFY.equalsIgnoreCase(saveType)) {//非保存修改模式下，序列号重新定义
									// 加入排序号
									to.put(SORT_ORDER_NO, i++);
								}
								Long subId = (Long)to.get(ID);
								if (null == subId) {
									// 新增
									//to.remove(ID);
									gsMngDao.save(to,
											subEntityName);
									//新增关联表数据
									saveReferEntity(subTe, subReferEntity, subEntityName, (Long)to.get(ID), true, subSplitTaList);
								} else {
									// 修改
									Map<String, Object> loadMap = gsMngDao
											.get(subId,
													subEntityName);
									copyMap(loadMap, to);
									//修改关联表数据
									saveReferEntity(subTe, subReferEntity, subEntityName, subId, false, subSplitTaList);
								}
							}
						}
					}
				} else if (DELETED.equals(en.getKey())) {
					// 删除
					if (null != en.getValue()
							&& en.getValue() instanceof List) {
						for (Object o : (List<Object>) en
								.getValue()) {
							if (o instanceof Map) {
								Map<String, Object> to = (Map<String, Object>) o;
								Long subId = ((Number)to.get(ID)).longValue();
								//先删除关联表数据
								deleteReferEntity(subTe.getIsReferCommon(), subTe.getReferEntityNameList(), subEntityName, subId);
								gsMngDao.delete(subId, subEntityName);
							}
						}
					}
				}
			}
		}
	}
	
	/**
	 * 保存子表数据，覆盖更新型
	 * 
	 * @param entity
	 */
	@SuppressWarnings("unchecked")
	public void saveReplaceSubEntity(Map<String, Object> dataMap) {
		String subEntityName = this.entityName;
		List<Object> idList = (List<Object>)dataMap.get(ID);
		if(idList != null && !idList.isEmpty()) {
			TableEntity subTe = TableEntityCache.getInstance().get(subEntityName);
			List<Object> subObjList = (List<Object>)dataMap.get(DATA);
			for(Object obj : idList) {
				Long id = ((Number)obj).longValue();
				Map<String, Object> entity = gsMngDao.get(id, subTe.getMasterEntityName()); //查询关联主表记录
				//先删除子表数据
				gsMngDao.deleteSubEntity(subEntityName, subTe.getRefEntityName(), id);
				//再保存子表数据
				if(subObjList != null && !subObjList.isEmpty()) { 
					Long i = 1L;
					for(Object subObj : subObjList) {
						Map<String, Object> tmpObj = (Map<String, Object>) subObj;
						Map<String, Object> to = new HashMap<String, Object>();
						copyMap(to, tmpObj);
						to.put(subTe.getRefEntityName(),
								entity);
						// 自动编号
						this.setAutoIdColumn(to, subEntityName);
						// 加入排序号
						to.put(SORT_ORDER_NO, i++);
						to.remove(ID);
						gsMngDao.save(to, subEntityName);
					}
				}
			}
		}
	}
	
	/**
	 * 处理空实体对象
	 * 
	 * @param loadMap
	 * @param mainEntityName
	 * @param mainEntityId
	 */
	public void handleEmptyEntity(Map<String, Object> loadMap, String mainEntityName, Long mainEntityId) {
		if(loadMap.isEmpty()) {
			//需要创建对象
			loadMap.put(ENTITY_ID, mainEntityId);
			loadMap.put(ENTITY_NAME, mainEntityName);
			loadMap.put(CREATE_TIME, new Date());
			loadMap.put(CREATE_USER, this.user.getId());
		}
	}
	
	/**
	 * 将一条数据根据拆分属性分拆出第2条数据并返回
	 * 
	 * @param te
	 * @param re
	 * @param splitTaList
	 * @return
	 */
	public Map<String,Object> splitOneToTwoObject(TableEntity te, Map<String,Object> re, List<TeAttr> splitTaList) {
		Map<String, Object> re2 = new HashMap<String, Object>();
		copyMap(re2, re);
		for(TeAttr ta : splitTaList) {
			String syncKey = ta.getSyncKey();
			String key = ta.getName();
			Object val = re2.get(key);
			re2.put(syncKey, val);
		}
		if(Form.STOCK_TYPE_OUT.equals(te.getInOutVal())) {
			re2.put(STOCK_RATIO, STOCK_RATIO_IN);
			re.put(STOCK_RATIO, STOCK_RATIO_OUT);
		} else {
			re2.put(STOCK_RATIO, STOCK_RATIO_OUT);
			re.put(STOCK_RATIO, STOCK_RATIO_IN);
		}
		return re2;
	}
	
	/**
	 * 删除关联表数据
	 * 
	 * @param isReferCommon
	 * @param referEntityNameList
	 * @param mainEntityName
	 * @param mainEntityId
	 */
	private void deleteReferEntity(Boolean isReferCommon, List<String> referEntityNameList, String mainEntityName, Long mainEntityId) {
		if(isReferCommon) {
			if(null!=referEntityNameList && !referEntityNameList.isEmpty()) {
				for(String referEntityName : referEntityNameList) {
					gsMngDao.deleteReferEntity(referEntityName, mainEntityName, mainEntityId);
				}
			}
		}
	}
	
	/**
	 * 将主表的部分字段数据同步至子表及关联表
	 * 
	 * @param taList
	 * @param entity
	 */
	private void syncDataBetweenEntitys(List<TeAttr> taList, Map<String, Object> entity) {
		for(TeAttr ta : taList) {
			String fromEntityName = ta.getFromEntityName();
			String syncEntityName = ta.getSyncEntityName();
			Long mainEntityId = (Long)entity.get(ID);
			String fieldName = ta.getName();
			Object val = entity.get(fieldName);
			if(syncEntityName.equals(fromEntityName)) {
				//更新子表
				TableEntity subTe = TableEntityCache.getInstance().get(syncEntityName);
				gsMngDao.updateSubEntity(syncEntityName, subTe.getRefEntityName(), mainEntityId, fieldName, val);
			} else {
				//更新关联表
				TableEntity subTe = TableEntityCache.getInstance().get(fromEntityName);
				gsMngDao.updateReferEntity(syncEntityName, fromEntityName, subTe.getRefEntityName(), fieldName, val, mainEntityId);
			}
		}
	}
	
	/**
	 * 发送消息列表
	 * 
	 * @param entity
	 * @param msgList
	 */
	@SuppressWarnings("unchecked")
	private void sendMessage(Map<String, Object> entity, Object msgList) {
		if(null!=msgList) {
			if(msgList instanceof List) {
				List<Object> objList = (List<Object>)msgList;
				if(!objList.isEmpty()) {
					for(Object obj : objList) {
						if(obj instanceof Map) {
							Map<String, Object>  message = (Map<String, Object>)obj;
							if(null!=message) {
								Long userId = NumberUtils.toLong(String.valueOf(message.get("userId")));
								if(userId!=null){
									message.put("style", Notice.STYLE_04);
									message.put("moduleDataId", entity.get(ID));
									message.put("moduleKey",this.entityName);
									sendAllMessage(message);
								}
							}
						}
					}
				}
			}
		}
	}
	
	/**
	 * 发送所有类型的通知消息
	 * 
	 * @param map 消息数据
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public void  sendAllMessage(Map<String, Object> message) {
		String userIds = String.valueOf(message.get("userId"));
		String userId [] = userIds.split(",");
		String noticeContent = String.valueOf(message.get("content"));
		String style = String.valueOf(message.get("style"));
		String title = String.valueOf(message.get("title"));
		Long owner = 0L;
		Notice notice = new Notice();
		notice.setStatus(Notice.STATUS_1);				
		notice.setCreateUser(this.user.getId());
		notice.setCreateTime(new Date());
		notice.setContent(noticeContent);
		notice.setTitle(title);
		if (Notice.STYLE_01.equals(style)) {
			notice.setStyle(Notice.STYLE_01);
		} else if (Notice.STYLE_02.equals(style)) {
			notice.setStyle(Notice.STYLE_02);
		} else if (Notice.STYLE_03.equals(style)) {
			notice.setStyle(Notice.STYLE_03);
		} else if (Notice.STYLE_04.equals(style)) {
			String moduleDataId = String.valueOf(message.get("moduleDataId"));
			String moduleKey = String.valueOf(message.get("moduleKey"));
			List<Map<String, Object>> fieldsList = (List<Map<String, Object>>) message.get("fields");
			String fields = jsonBinder.toJson(fieldsList);
			
			notice.setStyle(Notice.STYLE_04);
			notice.setModuleDataId(moduleDataId);
			notice.setModuleKey(moduleKey);
			notice.setModuleFields(fields);
		}else if (Notice.STYLE_06.equals(style)) {
			String moduleDataId = String.valueOf(message.get("moduleDataId"));
			String moduleKey = String.valueOf(message.get("moduleKey"));
			
			setEntityName(moduleKey);
			Long orderId = NumberUtils.toLong(moduleDataId);
			Map<String, Object> map = getEntity(orderId);
			owner = (Long) map.get("createUser");
			
			notice.setStyle(Notice.STYLE_06);
			notice.setModuleDataId(moduleDataId);
			notice.setModuleKey(moduleKey);
		}
		
		for(String uid : userId){
		NoticeToUser noticeToUser = new NoticeToUser();
		Long id = NumberUtils.toLong(uid);
		if(Notice.STYLE_06.equals(notice.getStyle())){
			if(owner.equals(id)){//表示发送业务通知给单据的拥有者
				 notice.setModuleFields("true");
		 	 }else{//表示发送业务通知给单据的非拥有者
			 	notice.setModuleFields("false");
		 	}
		}
		
		noticeToUser.setNotice(notice);
		noticeToUser.setStatus(NoticeToUser.STATUS_0);
		noticeToUser.setUserId(id);
		noticeDao.save(notice);
		noticeToUserDao.save(noticeToUser);
		}
	}
	
	/**
	 * 设置自动编号规则
	 * 
	 * @param entity
	 * @param ruleList
	 */
	@SuppressWarnings("unchecked")
	private void setAutoIdColumn(Map<String, Object> entity, Object ruleList) {
		if(null!=ruleList) {
			if(ruleList instanceof List) {
				List<Object> objList = (List<Object>)ruleList;
				if(!objList.isEmpty()) {
					for(Object obj : objList) {
						if(obj instanceof Map) {
							Map<String, Object> map = (Map<String, Object>)obj;
							String busVal = (String)map.get("busVal");//业务前缀
							String key = (String)map.get("key");
							String bitNum = (String)map.get("bitNum");//流水号位数
							String dateFmt = (String)map.get("dateFmt");//日期格式
							String excludeDate = (String)map.get("excludeDate");//排除日期
							String dateFirst = (String)map.get("dateFirst");//日期放在业务前缀之前
							Object ot = entity.get(key);
							if(null==ot || StringUtils.isBlank((String)ot)){
								String no = this.getAutoIdNo(entityName, key, busVal, NumberUtils.toInt(bitNum, 6), excludeDate, dateFmt, dateFirst);
								entity.put(key, no);
							}
						}
					}
				}
			}
		}
	}
	
	/**
	 * 设置自动编号规则，后台使用
	 * 
	 * @param entity
	 * @param ruleList
	 */
	@SuppressWarnings("unchecked")
	private void setAutoIdColumn(Map<String, Object> entity, String entityName) {
		Map<String, String> ruleMap = TableEntityCache.getInstance().getAutoIdRules(entityName);
		if(null!=ruleMap && !ruleMap.isEmpty()) {
			for(Map.Entry<String, String> rule : ruleMap.entrySet()) {
				String key = rule.getKey(); //字段属性
				Object ot = entity.get(key);
				if(null==ot || StringUtils.isBlank((String)ot)){
					String ruleVal = rule.getValue(); //自动编号规则
					ruleVal = this.preHandleAutoIdField(ruleVal, getUserParam(this.user));
					Map<String, Object> map = null;
					if(StringUtils.contains(ruleVal, "{")) {//对象
						map = jsonBinder.fromJson(ruleVal, HashMap.class);//转换自动编号规则
						if(map == null) {
							throw new GsException(key + "对应的自动编号规则配置不正确，规则为：" + ruleVal);
						}
					} else {//值
						map = new HashMap<String, Object>();
						ruleVal = StringUtils.replace(ruleVal, "\"", "");
						ruleVal = StringUtils.replace(ruleVal, "'", "");
						map.put("busVal", ruleVal);
					}
					String busVal = (String)map.get("busVal");//业务前缀
					String bitNum = (String)map.get("bitNum");//流水号位数
					String dateFmt = (String)map.get("dateFmt");//日期格式
					String excludeDate = (String)map.get("excludeDate");//排除日期
					String dateFirst = (String)map.get("dateFirst");//日期放在业务前缀之前
					
					String busRule = (String)map.get("busRule");//业务规则，用[key][caption][id]表示
					if(StringUtils.isNotBlank(busRule)) {
						busVal = genBianMaByGuiZe(busRule, entity);
					}
					
					String no = this.getAutoIdNo(entityName, key, busVal, NumberUtils.toInt(bitNum, 6), excludeDate, dateFmt, dateFirst);
					entity.put(key, no);
				}
			}
		}
	}
	
	/**
	 * 根据当前用户获取用户参数
	 * 
	 * @param user
	 * @return
	 */
	public Map<String, String> getUserParam(User user) {
		Map<String, String> param = new HashMap<String, String>();
		param.put("$curUserId$", String.valueOf(user.getId()));
		param.put("$curUserLoginName$", user.getLoginName());
		param.put("$curOrgId$", user.getOrganizationId());
		param.put("$curOrgName$", user.getOrganizationName());
		param.put("$curOrgCode$", user.getOrgCode());
		param.put("$curUserEmployeeId$", user.getEmployeeId());
		param.put("$curUserName$", user.getNickname());
		return param;
	}
	
	/**
	 * 预处理字段条件属性，替换系统变量属性
	 * 
	 * @param val
	 * @param param
	 * @return
	 */
	private String preHandleAutoIdField(String val, Map<String, String> param) {
		String result = val;
		for(Map.Entry<String, String> en : param.entrySet()) {
			result = StringUtils.replace(result, "["+en.getKey()+"]", en.getValue());
			result = StringUtils.replace(result, en.getKey(), "\"" + en.getValue() + "\"");
		}
		return result;
	}
	
	/**
	 * 根据编码规则生成编码，规则以"[name][key]"表示
	 * 
	 * @param guize
	 * @param result
	 * @return
	 */
	public static String genBianMaByGuiZe(String guize, Map<String, Object> result) {
		if(StringUtils.isNotBlank(guize)) {
			Pattern p = Pattern.compile("([^\\[]+?)(?=\\])"); 
			Matcher m = p.matcher(guize);
			String bm = guize;
			while(m.find()) {
				String attr = m.group();
				bm = StringUtils.replace(bm, "[" + attr + "]", (String)result.get(attr)); // 替换维度属性
			}
			bm = StringUtils.replace(bm, "空", ""); // 替换空值
			return bm;
		} else {
			return "";
		}
	}
	
	/**
	 * 获取自动生成流水号
	 * 由业务值+日期（年月日）+流水号组成
	 * 
	 * @param entityName 表实体
	 * @param key 字段key
	 * @param busVal 业务值 
	 * @param serialNoLen 流水号长度
	 * @param excludeDate 去除日期格式  1--去除
	 * @param dateFmt 日期格式，默认为yyyyMMdd
	 * @param dateFirst 日期在先
	 * @return 生成的流水号
	 */
	public String getAutoIdNo(String entityName, String key, String busVal, Integer serialNoLen, String excludeDate, String dateFmt, String dateFirst) {
		String bVal = StringUtils.defaultIfEmpty(busVal, "");
		String dateStr = DateFormatUtils.format(System.currentTimeMillis(), StringUtils.defaultIfEmpty(dateFmt, "yyyyMMdd"));
		if(!Constants.ENABLED.equals(excludeDate)) {
			//附加日期
			if(Constants.ENABLED.equals(dateFirst)) {//日期为先
				bVal = dateStr + bVal;
			} else {//业务值为先
				bVal = bVal + dateStr;
			}
		}
		StringBuffer sb = new StringBuffer();
		sb.append(bVal);
		if(serialNoLen > 0) {//等于0，不需要处理
			String maxNo = gsMngDao.getMaxAutoIdNo(entityName, key, bVal);
			if(StringUtils.isNotBlank(maxNo)) {
				//String no = StringUtils.right(maxNo, serialNoLen);
				int start = bVal.length();
				int end = start + serialNoLen;
				String no = StringUtils.substring(maxNo, start, end);
				Integer val = Integer.valueOf(no) + 1;
				sb.append(StringUtils.leftPad(String.valueOf(val), serialNoLen, "0"));
			} else {
				sb.append(StringUtils.leftPad("1", serialNoLen, "0"));
			}
		}
		return sb.toString();
	}

	/**
	 * 根据ID获取实体
	 * 
	 * @param id
	 * @return
	 */
	@Transactional(readOnly = true)
	public Map<String, Object> getEntity(Long id) {
		return this.preHandlePageData(gsMngDao.get(id));
	}
	
	/**
	 * 根据ID获取实体
	 * 
	 * @param id
	 * @param entityName
	 * @return
	 */
	@Transactional(readOnly = true)
	public Map<String, Object> getEntityByHql(Long id) {
		String sqlKey = entityName + com.qyxx.platform.gsc.utils.Constants.NAME_SPLIT_SYMBOL
					+ com.qyxx.platform.gsc.utils.Constants.QUERY_LIST_SQL_KEY;
		String hqlSelect = SqlCache.getInstance().getSqlContent(sqlKey);
		List<PropertyFilter> filters = new ArrayList<PropertyFilter>();
		PropertyFilter pf = new PropertyFilter("EQL_id", String.valueOf(id));
		filters.add(pf);
		List<Map<String, Object>> list = gsMngDao.find(hqlSelect, filters);
		return this.preHandlePageData(list.get(0));
	}

	/**
	 * 根据ID删除实体
	 * 
	 * @param id
	 */
	public void deleteEntity(Long id) {
		gsMngDao.delete(id);
	}

	/**
	 * 根据ID数组删除实体
	 * 
	 * @param ids
	 */
	public void deleteEntity(Long[] ids) {
		List<TableEntity> subEntityList = new ArrayList<TableEntity>();
		TableEntity te = TableEntityCache.getInstance().get(this.entityName);
		List<TableEntity> subTiList = te.getSubEntitys();
		if (null != subTiList && !subTiList.isEmpty()) {
			for (TableEntity subEntity : subTiList) {
				String subEntityName = subEntity.getEntityName();
				TableEntity subTe = TableEntityCache.getInstance().get(subEntityName);
				subEntityList.add(subTe);
			}
		}
		for (Long id : ids) {
			//检查记录是否被别的模块使用
			String assoEntityName = checkTableAssociatedWithAnother(this.entityName, id);
			if(null!=assoEntityName) {
				String moduleName = TableEntityCache.getInstance().getModuleNameByEntityName(assoEntityName);
				String teName = "(" + assoEntityName + ")";
				TableEntity tete = TableEntityCache.getInstance().get(assoEntityName);
				if(null!=tete) teName = tete.getCaption() + teName;
				throw new GsException("系统编号为" + id + "的记录被模块[" + moduleName + "]实体表[" + teName + "]引用，不允许删除");
			}
			//先删除主表关联表数据
			deleteReferEntity(te.getIsReferCommon(), te.getReferEntityNameList(), this.entityName, id);
			//再删除子表关联表数据
			for(TableEntity subTe : subEntityList) {
				if(subTe.getIsReferCommon()) {
					List<String> reList = subTe.getReferEntityNameList();
					if(null!=reList && !reList.isEmpty()) {
						//循环关联表
						for(String referEntityName : reList) {
							gsMngDao.deleteReferEntity(referEntityName, subTe.getEntityName(), subTe.getRefEntityName(), id);
						}
					}
				}
			}
			//删除主、子表数据
			gsMngDao.delete(id);
		}
	}

	/**
	 * 删除实体
	 * 
	 * @param entity
	 */
	public void deleteEntity(Map<String, Object> entity) {
		gsMngDao.delete(entity);
	}
	
	/**
	 * 检查实体字段有没有被其他实体引用关联
	 * 
	 * @param entityName
	 * @param id
	 * @return
	 */
	public String checkTableAssociatedWithAnother(String entityName, Long id) {
		String result = null;
		Map<String, String> refMap = SqlCache.getInstance().getReferTableField(entityName);
		if(null!=refMap && !refMap.isEmpty()) {
			for(Map.Entry<String, String> en : refMap.entrySet()) {
				String entityField = en.getKey();
				String idKeyVal = en.getValue();//被其他实体引用的实体对应的实体字段属性+引用实体的字段类型
				String[] ikv = StringUtils.split(idKeyVal, com.qyxx.platform.gsc.utils.Constants.NAME_SPLIT_SYMBOL);
				String idKey = ikv[0];//引用实体字段类型
				String refFieldDataType = ikv[1];//引用实体字段类型
				String[] efs = StringUtils.split(entityField, com.qyxx.platform.gsc.utils.Constants.NAME_SPLIT_SYMBOL);
				if(efs.length >= 3) {
					//引用实体名
					String refEntityName = efs[0] + com.qyxx.platform.gsc.utils.Constants.NAME_SPLIT_SYMBOL + efs[1];
					String refFieldName = efs[2];//引用实体字段
					Object idVal = id;
					if(!ID.equalsIgnoreCase(idKey)) {
						//非id字段
						idVal = gsMngDao.get(id).get(idKey);
					}
					if(null!=idVal) {//过滤null值字段
						Object val = convertObjectToRealType(refFieldDataType, idVal);
						if(null!=val) {
							Map<String,Object> param = new HashMap<String,Object>();
							param.put(refFieldName, val);
							Long count = gsMngDao.getEntityCountByHql(refEntityName, param);
							if(count > 0) {
								return refEntityName;
							}
						}
					}
				}
			}
		}
		return result;
	}

	/**
	 * 分页查询列表
	 * 
	 * @param page
	 * @param filters
	 * @return
	 */
	@Transactional(readOnly = true)
	public Page<Map<String, Object>> searchEntity(
			final Page<Map<String, Object>> page,
			final List<PropertyFilter> filters) {
		return preHandlePageData(gsMngDao.findPage(page, filters));
	}
	
	/**
	 * 分页查询列表
	 * 
	 * @param page
	 * @param filters
	 * @param entityName
	 * @return
	 */
	@Transactional(readOnly = true)
	public Page<Map<String, Object>> searchEntityByHql(
			final Page<Map<String, Object>> page,
			final List<PropertyFilter> filters) {
		String sqlKey = entityName + com.qyxx.platform.gsc.utils.Constants.NAME_SPLIT_SYMBOL
						+ com.qyxx.platform.gsc.utils.Constants.QUERY_LIST_SQL_KEY;
		String hqlSelect = SqlCache.getInstance().getSqlContent(sqlKey);
		return preHandlePageData(gsMngDao.findPage(hqlSelect, page, filters));
	}
	
	/**
	 * 分页查询列表
	 * 固定参数+动态参数模式
	 * 
	 * @param page
	 * @param filters
	 * @param fixFilters
	 * @return
	 */
	@Transactional(readOnly = true)
	public Page<Map<String, Object>> searchEntityByHql(
			final Page<Map<String, Object>> page,
			final List<PropertyFilter> filters,
			final List<PropertyFilter> fixFilters) {
		String sqlKey = entityName + com.qyxx.platform.gsc.utils.Constants.NAME_SPLIT_SYMBOL
						+ com.qyxx.platform.gsc.utils.Constants.QUERY_LIST_SQL_KEY;
		Sql sql = SqlCache.getInstance().getSql(sqlKey);
		String hqlSelect = sql.getContent(); //SqlCache.getInstance().getSqlContent(sqlKey);
		hqlSelect = this.setFixSysParamFilter(hqlSelect, fixFilters, sql);//设置系统参数
		return preHandlePageData(gsMngDao.findPage(hqlSelect, page, filters, fixFilters));
	}
	
	/**
	 * 查询列表，加排序
	 * 
	 * @param page
	 * @param filters
	 * @return
	 */
	@Transactional(readOnly = true)
	public List<Map<String, Object>> findList(
			final Page<Map<String, Object>> page,
			final List<PropertyFilter> filters) {
		return gsMngDao.find(filters, page);
	}
	
	/**
	 * 根据sql语句查询列表，加排序
	 * 
	 * @param page
	 * @param filters
	 * @param entityName
	 * @return
	 */
	@Transactional(readOnly = true)
	public List<Map<String, Object>> findListByHql(
			final Page<Map<String, Object>> page,
			final List<PropertyFilter> filters, String eName) {
		String sqlKey = eName + com.qyxx.platform.gsc.utils.Constants.NAME_SPLIT_SYMBOL
						+ com.qyxx.platform.gsc.utils.Constants.QUERY_LIST_SQL_KEY;
		String hqlSelect = SqlCache.getInstance().getSqlContent(sqlKey);
		return gsMngDao.find(hqlSelect, filters, page);
	}

	/**
	 * 条件查询列表，不加排序
	 * 
	 * @param filters
	 * @return
	 */
	@Transactional(readOnly = true)
	public List<Map<String, Object>> findList(
			final List<PropertyFilter> filters) {
		return gsMngDao.find(filters);
	}
	
	/**
	 * 根据sql语句条件查询列表，不加排序
	 * 
	 * @param filters
	 * @param eName
	 * @return
	 */
	@Transactional(readOnly = true)
	public List<Map<String, Object>> findListByHql(
			final List<PropertyFilter> filters, String eName) {
		String sqlKey = eName + com.qyxx.platform.gsc.utils.Constants.NAME_SPLIT_SYMBOL
				+ com.qyxx.platform.gsc.utils.Constants.QUERY_LIST_SQL_KEY;
		String hqlSelect = SqlCache.getInstance().getSqlContent(sqlKey);
		return gsMngDao.find(hqlSelect, filters);
	}

	/**
	 * 根据sqlKey查找sql对应的sql语句并执行查询方法
	 * 
	 * @param sqlKey
	 *            sql语句key
	 * @param filters
	 *            参数及参数值
	 * @return
	 */
	@Transactional(readOnly = true)
	public List<Map<String, Object>> queryList(String sqlKey,
			final List<PropertyFilter> filters) {
		// String sql =
		// "select QUALITY, PRODUCT_ITEM from GS_ContractsSheet where MASTER_ID = :masterId";
		// 从缓存中获取SQL语句
		return queryList(sqlKey, filters, true);
	}

	/**
	 * 根据sqlKey查找sql对应的sql语句并执行查询方法
	 * 
	 * @param sqlKey
	 *            sql语句key
	 * @param filters
	 *            参数及参数值
	 * @param isAppendWhere
	 *            是否加上where条件
	 * @return
	 */
	@Transactional(readOnly = true)
	public List<Map<String, Object>> queryList(String sqlKey,
			final List<PropertyFilter> filters, Boolean isAppendWhere) {
		// String sql =
		// "select QUALITY, PRODUCT_ITEM from GS_ContractsSheet where MASTER_ID = :masterId";
		// 从缓存中获取SQL语句
		Sql sql = SqlCache.getInstance().getSql(sqlKey);		
		if (null == sql) {
			throw new GsException(sqlKey + "对应的sql找不到");
		}
		String strSql = getSqlWithCheckDataAuth(sql, filters, isAppendWhere);
		return gsMngDao.findBy(strSql, filters);
	}
	
	/**
	 * 根据filter和pager数量查询数据
	 * 
	 * @param sqlKey
	 * @param filters
	 * @param isAppendWhere
	 * @param page
	 * @return
	 */
	@Transactional(readOnly = true)
	public List<Map<String, Object>> queryPage(String sqlKey,
			final List<PropertyFilter> filters, Boolean isAppendWhere, Page<Map<String, Object>> page) {
		Sql sql = SqlCache.getInstance().getSql(sqlKey);		
		if (null == sql) {
			throw new GsException(sqlKey + "对应的sql找不到");
		}
		String strSql = getSqlWithCheckDataAuth(sql, filters, isAppendWhere);
		strSql = "SELECT * from (" + strSql + ") a";
		List<Map<String, Object>> list = gsMngDao.findPage(strSql, page, filters).getResult();
		return convertListBySql(sql, list);
	}
	
	/**
	 * 根据sqlKey,filter和pager数量查询数据
	 * 
	 * 根据sql语句查询，用于dialoguewindow控件查询分页数据
	 * 
	 * @param sqlKey
	 * @param filters
	 * @param isAppendWhere
	 * @param page
	 * @return
	 */
	@Transactional(readOnly = true)
	public Page<Map<String, Object>> querySqlPageByFilter(String sqlKey,
			final List<PropertyFilter> filters, final List<PropertyFilter> fixFilters, Boolean isAppendWhere, Page<Map<String, Object>> page) {
		Sql sql = SqlCache.getInstance().getSql(sqlKey);		
		if (null == sql) {
			throw new GsException(sqlKey + "对应的sql找不到");
		}
		String strSql = sql.buildSql(isAppendWhere); //getSqlWithCheckDataAuth(sql, filters, isAppendWhere);
		strSql = "SELECT * from (" + strSql + ") a where 1=1 ";
		//List<PropertyFilter> fixFilters = Lists.newArrayList();
		strSql = this.setFixSysParamFilter(strSql, fixFilters, sql);//设置系统参数
		//return preHandlePageData(gsMngDao.findPage(strSql, page, filters, fixFilters));
		Page<Map<String, Object>> resultPage = gsMngDao.findPage(strSql, page, filters, fixFilters);
		List<Map<String, Object>> list = convertListBySql(sql, resultPage.getResult());
		resultPage.setResult(list);
		return resultPage;
	}
	
	/**
	 * 根据q条件和pageSize数量查询数据
	 * 
	 * @param sqlKey
	 * @param filters
	 * @param isAppendWhere
	 * @param q
	 * @param pageSize
	 * @return
	 */
	@Transactional(readOnly = true)
	public List<Map<String, Object>> queryList(String sqlKey,
			final List<PropertyFilter> filters, Boolean isAppendWhere, String q, int pageSize, Boolean isCaptionQuery) {
		// String sql =
		// "select QUALITY, PRODUCT_ITEM from GS_ContractsSheet where MASTER_ID = :masterId";
		// 从缓存中获取SQL语句
		Sql sql = SqlCache.getInstance().getSql(sqlKey);		
		if (null == sql) {
			throw new GsException(sqlKey + "对应的sql找不到");
		}
		String strSql = getSqlWithCheckDataAuth(sql, filters, isAppendWhere);
		strSql = getSqlWithQ(strSql, sql, filters, q, false, isCaptionQuery);
		List<Map<String, Object>> list = gsMngDao.findBy(strSql, filters, pageSize);
		return convertListBySql(sql, list);
	}
	
	/**
	 * 执行hql语句查询，并返回list结果
	 * 
	 * @param sqlKey
	 * @param filters
	 * @return
	 */
	@Transactional(readOnly = true)
	public List<Map<String, Object>> queryHqlList(String sqlKey,
			final List<PropertyFilter> filters) {
		return queryHqlList(sqlKey, filters, true);
	}
	
	/**
	 * 执行hql语句查询，并返回list结果
	 * 
	 * @param sqlKey
	 * @param filters
	 * @param isAppendWhere
	 * @return
	 */
	@Transactional(readOnly = true)
	public List<Map<String, Object>> queryHqlList(String sqlKey,
			final List<PropertyFilter> filters,  Boolean isAppendWhere) {
		Sql sql = SqlCache.getInstance().getSql(sqlKey);		
		if (null == sql) {
			throw new GsException(sqlKey + "对应的sql找不到");
		}
		String strSql = sql.buildHql(isAppendWhere);
		if (StringUtils.isBlank(strSql)) {
			throw new GsException(sqlKey + "对应的sql找不到");
		}
		checkDataAuth(strSql, sql, filters);
		return gsMngDao.findByHql(strSql, filters);
	}
	
	/**
	 * 根据q条件及数量查询HQL记录集
	 * 
	 * @param sqlKey
	 * @param filters
	 * @param isAppendWhere
	 * @param q
	 * @param pageSize
	 * @return
	 */
	@Transactional(readOnly = true)
	public List<Map<String, Object>> queryHqlList(String sqlKey,
			final List<PropertyFilter> filters,  Boolean isAppendWhere, String q, 
			int pageSize, Boolean isCaptionQuery) {
		Sql sql = SqlCache.getInstance().getSql(sqlKey);		
		if (null == sql) {
			throw new GsException(sqlKey + "对应的sql找不到");
		}
		String strSql = sql.buildHql(isAppendWhere);
		if (StringUtils.isBlank(strSql)) {
			throw new GsException(sqlKey + "对应的sql找不到");
		}
		checkDataAuth(strSql, sql, filters);
		strSql = getSqlWithQ(strSql, sql, filters, q, true, isCaptionQuery);
		List<Map<String, Object>> list = gsMngDao.findByHql(strSql, filters, pageSize);
		return convertListBySql(sql, list);
	}
	
	
	/**
	 * 执行hql语句查询，并返回list结果
	 * 
	 * @param sqlKey
	 * @param filters
	 * @param isAppendWhere
	 * @return
	 */
	@Transactional(readOnly = true)
	public List<Map<String, Object>> queryHqlPage(String sqlKey,
			final List<PropertyFilter> filters,  Boolean isAppendWhere, Page<Map<String, Object>> page) {
		Sql sql = SqlCache.getInstance().getSql(sqlKey);		
		if (null == sql) {
			throw new GsException(sqlKey + "对应的sql找不到");
		}
		String strSql = sql.buildHql(isAppendWhere);
		if (StringUtils.isBlank(strSql)) {
			throw new GsException(sqlKey + "对应的sql找不到");
		}
		checkDataAuth(strSql, sql, filters);
		strSql = gsMngDao.buildHqlByPropertyFilter(strSql, filters);
		List<Map<String, Object>> list = gsMngDao.findByHql(strSql, filters, page);
		return convertListBySql(sql, list);
	}
	
	/**
	 * 根据模块hql,filter和pager数量查询数据
	 * 
	 * 根据hql语句查询，用于dialoguewindow控件查询分页数据
	 * 
	 * @param sqlKey
	 * @param filters
	 * @param isAppendWhere
	 * @param page
	 * @return
	 */
	@Transactional(readOnly = true)
	public Page<Map<String, Object>> queryHqlPageByFilter(String sqlKey,
			final List<PropertyFilter> filters, final List<PropertyFilter> fixFilters,  Boolean isAppendWhere, Page<Map<String, Object>> page) {
		Sql sql = SqlCache.getInstance().getSql(sqlKey);		
		if (null == sql) {
			throw new GsException(sqlKey + "对应的sql找不到");
		}
		String strSql = sql.buildHql(isAppendWhere);
		if (StringUtils.isBlank(strSql)) {
			throw new GsException(sqlKey + "对应的sql找不到");
		}
		checkDataAuth(strSql, sql, filters);//模块没有固定参数
		strSql = gsMngDao.buildHqlByPropertyFilter(strSql, filters);//hql添加动态参数
		filters.addAll(fixFilters);//设置固定参数
		Page<Map<String, Object>> resultPage = gsMngDao.findPageByHql(strSql, filters, page);
		List<Map<String, Object>> list = convertListBySql(sql, resultPage.getResult());
		resultPage.setResult(list);
		return resultPage;
	}
	
	
	/**
	 * 数据权限过滤，增加过滤条件
	 *
	 * @param filters
	 * @param isCheckAuth
	 * @param sql
	 * 
	 * @return
	 */
	private String getSqlWithCheckDataAuth(Sql sql, List<PropertyFilter> filters, Boolean isAppendWhere) {
		String strSql = sql.buildSql(isAppendWhere);
		if (StringUtils.isBlank(strSql)) {
			throw new GsException(sql.getKey() + "对应的sql找不到");
		}
		strSql = checkDataAuth(strSql, sql, filters);
		return strSql;
	}
	
	/**
	 * 获取加入动态查询条件的sql语句
	 * 
	 * @param strSql
	 * @param filters
	 * @param dynamicFilters
	 * @return
	 */
	private String getSqlWithAppendDynamicFilters(String strSql, List<PropertyFilter> filters, List<PropertyFilter> dynamicFilters) {
		String sql = strSql;
		if(null!=dynamicFilters && !dynamicFilters.isEmpty()) {
			sql = gsMngDao.buildHqlByPropertyFilter(strSql, dynamicFilters);
			filters.addAll(dynamicFilters);
		}
		return sql;
	}
	
	/**
	 * 检查数据权限
	 * 
	 * @param strSql
	 * @param sql
	 * @param filters
	 */
	private String checkDataAuth(String strSql, Sql sql, List<PropertyFilter> filters) {
		if(sql.getIsCheckAuth()) {
			this.setCreateUsersFilter(sql, filters);
			
			//添加共享用户
			/*List<TeAttr> taList = TableEntityCache.getInstance().getUseAsShareUserAttrMap(sql.getEntityName());
			if(null!=taList && !taList.isEmpty()) { 
				for(TeAttr ta : taList) {
					PropertyFilter p = new PropertyFilter("EQL_" + ta.getName(), String.valueOf(user.getId()));
					pf.addOrPropertyFilter(p);
				}
			}*/
			//filters.add(pf);
		}/* else {
			//判断存在:createUsers属性
			if(strSql.indexOf(":"+Sql.CREATE_USERS) > 0) {
				//判断存在:createUser 属性
				PropertyFilter pf = new PropertyFilter("INL_" + Sql.CREATE_USERS, String.valueOf(user.getId()));
				filters.add(pf);
			}
		}*/
		return setFixSysParamFilter(strSql, filters, sql);
	}
	
	private void setCreateUsersFilter(Sql sql, List<PropertyFilter> filters) {
		List<String> dataAuthList = user.getDataAuthList();
		PropertyFilter pf = new PropertyFilter("INL_" + Sql.CREATE_USERS, "0");
		if(sql != null && null!=dataAuthList && !dataAuthList.isEmpty()) {
			String authKey = Constants.RESOURCE_DATA_IN_ORG + Constants.UNDERLINE + sql.getEntityName();
			if(dataAuthList.contains(authKey)) {
				//获取同部门下所有用户
				List<Long> userIdList = accountManager.findUserInSameOrg(user.getOrgCode());
				pf = new PropertyFilter("INL_" + Sql.CREATE_USERS, StringUtils.join(userIdList, ","));		
			} else {
				//有权看自己创建的数据
				pf = new PropertyFilter("INL_" + Sql.CREATE_USERS, String.valueOf(user.getId()));
			}
		} else {
			//没有数据权限时，有权看自己创建的数据
			pf = new PropertyFilter("INL_" + Sql.CREATE_USERS, String.valueOf(user.getId()));
		}
		filters.add(pf);
	}
	
	/**
	 * 设置固定系统参数
	 * 
	 * @param strSql
	 * @param filters
	 */
	private String setFixSysParamFilter(String strSql, List<PropertyFilter> filters, Sql sql) {
		strSql = parseDynamicSql(strSql, filters);//先解析得到正确的sql语句，再做条件判断
		if(strSql.indexOf(":"+Sql.CREATE_USERS) > 0) {
			this.setCreateUsersFilter(sql, filters);
		}
		if(strSql.indexOf(":"+GsMngManager.CREATE_USER+" ") > 0) {
			//判断存在:createUser 属性
			PropertyFilter pf = new PropertyFilter("EQL_" + GsMngManager.CREATE_USER, String.valueOf(user.getId()));
			filters.add(pf);
		}
		if(strSql.indexOf(":"+GsMngManager.PARENT_ORG_CODES) > 0) {
			//判断存在:parentOrgCodes属性
			List<String> poc = Organization.getSplitCodeList(user.getOrgCode());
			PropertyFilter pf = new PropertyFilter("INS_" + GsMngManager.PARENT_ORG_CODES, StringUtils.join(poc, ","));
			filters.add(pf);
		}
		if(strSql.indexOf(":"+GsMngManager.ORG_CODE) > 0) {
			//判断存在:orgCode属性
			String code = user.getOrgCode() + "%";
			PropertyFilter pf = new PropertyFilter("LIKES_" + GsMngManager.ORG_CODE, code);
			filters.add(pf);
		}
		return strSql;
	}
	
	/**
	 * 解析动态sql语句，加入当前用户对象，进行动态参数设置
	 * 
	 * @param strSql
	 * @param filters
	 * @return
	 */
	private String parseDynamicSql(String strSql, List<PropertyFilter> filters) {
		Map<String, Object> params = new HashMap<String, Object>();
		gsMngDao.preHandleFixFilter(filters, params);
		params.put("USER", user);
		return DynamicSqlUtils.parseSqlByFreeMarker(strSql, params);
	}
	
	/**
	 * 获取加入了q条件的sql语句
	 * 
	 * @param strSql
	 * @param sql
	 * @param filters
	 * @param q
	 * @param isHql
	 * @return
	 */
	public String getSqlWithQ(String strSql, Sql sql, List<PropertyFilter> filters, String q, Boolean isHql) {
		StringBuffer sb = new StringBuffer("");
		if(StringUtils.isNotBlank(q)) {
			List<Item> items = sql.getSetValueItemList();
			String column = null;
			for(Item it : items) {
				if("caption".equals(it.getKey())) { //caption对应字段即为查询条件
					column = it.getColumn();
					break;
				}
			}
			if(column != null) { //增加q查询条件
				if(isHql) {
					sb.append(strSql);
					sb.append(" AND ");
				} else {
					sb.append("select a.* from (");
					sb.append(strSql);
					sb.append(") a where a.");
				}
				sb.append(column);
				sb.append(" like :q ");
				PropertyFilter pf = new PropertyFilter("LIKES_q", "%"+q+"%");
				filters.add(pf);
			} else {
				sb.append(strSql);
			}
		} else {
			sb.append(strSql);
		}
		return sb.toString();
	}
	
	/**
	 * 获取加入了q条件的sql语句
	 * 
	 * @param strSql
	 * @param sql
	 * @param filters
	 * @param q
	 * @param isHql
	 * @return
	 */
	public String getSqlWithQ(String strSql, Sql sql, List<PropertyFilter> filters, String q, Boolean isHql, Boolean isCaptionQuery) {
		StringBuffer sb = new StringBuffer("");
		if(isHql) {//支持模块动态查询条件
			strSql = gsMngDao.buildHqlByPropertyFilter(strSql, filters);
		}
		if(StringUtils.isNotBlank(q)) {
			List<Item> items = sql.getSetValueItemList();
			List<Item> column = new ArrayList<Item>();
			String columnType = "S";
			for(Item it : items) {
				if(isCaptionQuery && (!Item.OPERATOR_NONE.equalsIgnoreCase(it.getOperator()))
						&& ("caption".equalsIgnoreCase(it.getKey()) 
							|| "text".equalsIgnoreCase(it.getKey())
							|| Item.COLUMN_TYPE_STRING.equalsIgnoreCase(it.getColumntype()))) { //caption对应字段即为查询条件，字符串字段也纳入查询条件
					column.add(it);
				} else if(!isCaptionQuery 
						&& ("key".equalsIgnoreCase(it.getKey()) || "id".equalsIgnoreCase(it.getKey()))) {
					column.add(it);
					if(Item.COLUMN_TYPE_LONG.equalsIgnoreCase(it.getColumntype())
							|| "id".equalsIgnoreCase(it.getColumn())) {//long类型或者ID字段
						columnType = "L";
					}
					break;
				}
			}
			if(!column.isEmpty()) { //增加q查询条件
				if(isHql) {
					sb.append(strSql);
					sb.append(" AND ");
				} else {
					sb.append("select a.* from (");
					sb.append(strSql);
					sb.append(") a where ");
				}
				sb.append("(");
				StringBuffer whereSb = new StringBuffer();
				int len = column.size();
				for(Item it : column) {
					if(isCaptionQuery && Item.OPERATOR_FULLTEXT.equalsIgnoreCase(it.getOperator())) {
						whereSb.append("MATCH(");
					}
					String col = it.getColumn();
					if(!isHql) {
						whereSb.append("a.");
					}
					whereSb.append(col);
					if(isCaptionQuery) {
						if(Item.OPERATOR_LIKEL.equalsIgnoreCase(it.getOperator())) {//开始于
							whereSb.append(" like :q ");
							PropertyFilter pf = new PropertyFilter("LIKES_q", q + "%");
							filters.add(pf);
						} else if(Item.OPERATOR_FULLTEXT.equalsIgnoreCase(it.getOperator())) {//全文检索
							whereSb.append(") AGAINST(:q) ");
							PropertyFilter pf = new PropertyFilter("EQS_q", q);
							filters.add(pf);
							//whereSb.append(q);
							//whereSb.append("') ");
						} else {//默认like
							whereSb.append(" like :q ");
							PropertyFilter pf = new PropertyFilter("LIKES_q", "%"+q+"%");
							filters.add(pf);
						}
					} else {
						whereSb.append(" IN (:q) ");
						PropertyFilter pf = new PropertyFilter("IN" + columnType + "_q", q);
						filters.add(pf);
					}
					if(--len > 0) {
						whereSb.append(" OR ");
					}
				}
				sb.append(whereSb.toString());
				sb.append(")");
			} else {
				sb.append(strSql);
			}
		} else {
			sb.append(strSql);
		}
		return sb.toString();
	}

	/**
	 * 将Map对象中的String类型转成对应与数据库的java实际类型
	 * 返回关联实体对象
	 * 
	 * @param entity
	 * @param te
	 * @param syncTaList
	 * @param splitTaList
	 * @return
	 */
	public Map<String, Map<String, Object>> prepareMapObj(Map<String, Object> entity,
			TableEntity te, List<TeAttr> syncTaList, List<TeAttr> splitTaList) {
		Map<String, Map<String, Object>> obj = convertMapObj(entity, te, syncTaList, splitTaList);
		// 处理主键
		Object id = entity.get(ID);
		if (null != id) {
			entity.put(LAST_UPDATE_USER, this.user.getId());
			entity.put(LAST_UPDATE_TIME, new Date());
			if(te.getIsReferCommon()) {
				//处理关联表
				for(Map.Entry<String, Map<String, Object>> en : obj.entrySet()) {
					en.getValue().put(LAST_UPDATE_USER, this.user.getId());
					en.getValue().put(LAST_UPDATE_TIME, new Date());
				}
			}
		} else {
			entity.put(CREATE_USER, this.user.getId());
			entity.put(CREATE_TIME, new Date());
			if(te.getIsReferCommon()) {
				//处理关联表
				for(Map.Entry<String, Map<String, Object>> en : obj.entrySet()) {
					en.getValue().put(CREATE_USER, this.user.getId());
					en.getValue().put(CREATE_TIME, new Date());
				}
			}
		}
		return obj;
	}

	/**
	 * 转换实体，返回关联实体对象，同时处理需同步主、子表及关联表数据的属性，以及需拆分的属性
	 * 
	 * @param entity
	 * @param te
	 * @param syncTaList
	 * @param splitTaList
	 * @return
	 */
	public Map<String, Map<String, Object>> convertMapObj(Map<String, Object> entity,
			TableEntity te, List<TeAttr> syncTaList, List<TeAttr> splitTaList) {
		List<TeAttr> attrs = te.getTeAttr();
		Map<String, Map<String, Object>> referMap = new HashMap<String, Map<String, Object>>();
		if (null != attrs && !attrs.isEmpty()) {
			for (TeAttr ta : attrs) {
				String attrName = ta.getName();
				Object attrVal = entity.get(attrName);
				if (null != attrVal) {
					Object val = convertObjectToRealType(ta.getType(), attrVal);
					if(StringUtils.isNotBlank(ta.getEntityName())) {
						//关联表数据
						prepareReferEntity(referMap, ta.getEntityName(), attrName, val);
					} else {
						entity.put(attrName, val);
					}
				}
				//处理同步数据属性
				if(null!=syncTaList) {
					if(StringUtils.isNotBlank(ta.getSyncEntityName())) {
						syncTaList.add(ta);
					}
				}
				//处理拆分数据属性
				if(null!=splitTaList) {
					if(StringUtils.isNotBlank(ta.getSyncKey())) {
						splitTaList.add(ta);
					}
				}
			}
		}
		//handleLongProperties(entity, VERSION, 0L);
		//handleLongProperties(entity, SORT_ORDER_NO, 0L);
		//handleLongProperties(entity, ATM_ID, null);
		return referMap;
	}
	
	/**
	 * 将Object类型值转换成对应的实际类型值
	 * 
	 * @param dataType
	 * @param strVal
	 * @return
	 */
	public Object convertObjectToRealType(String dataType, Object attrVal) {
		String strVal = String.valueOf(attrVal);
		Object val = null;
		if (StringUtils.isBlank(strVal)) {
			val = null;
		} else {
			GsDataType gsDataType = Enum.valueOf(
					GsDataType.class, dataType
							.toUpperCase());
			switch (gsDataType) {
			case DTLONG: // Long
			case DTINTEGER: // Int
			case DTSHORT: // Short
				val = NumberUtils.toLong(strVal);
				break;
			case DTDATETIME: // Date
				Date date = new Date();
				try {
					date = DateUtils
							.parseDate(
									strVal,
									new String[] {
											"yyyy-MM-dd",
											"yyyy-MM-dd HH:mm:ss",
											"yyyy-MM-dd HH:mm",
											"yyyy-MM",
											"HH:mm:ss",
											"HH:mm",
											"yyyy-MM-dd HH",
											"MM-dd","yyyy","HH"});
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				val = date;
				break;
			case DTFLOAT: // Float
			case DTDOUBLE: // Double
				val = new BigDecimal(strVal);
				break;
			case DTSTRING: // String
			case DTIMAGE: // Image
			case DTTEXT: // Text
				val = strVal;
				break;
			default:
				val = strVal;
				break;
			}
		}
		return val;
	}
	
	/**
	 * 预处理关联实体对象
	 * 
	 * @param referMap
	 * @param entityName
	 * @param attrName
	 * @param val
	 */
	private void prepareReferEntity(Map<String, Map<String, Object>> referMap, String entityName, String attrName, Object val) {
		Map<String, Object> obj = referMap.get(entityName);
		if(null == obj) {
			obj = new HashMap<String, Object>();
			referMap.put(entityName, obj);
		}
		obj.put(attrName, val);
	}

	/**
	 * 处理null值，以默认值替代
	 * 
	 * @param entity
	 * @param key
	 * @param defaultVal
	 */
	public void handleLongProperties(Map<String, Object> entity,
			String key, Object defaultVal) {
		Object version = entity.get(key);
		if (null == version) {
			entity.put(key, defaultVal);
		}
	}

	/**
	 * 根据ID获取实体
	 * 
	 * @param id
	 * @return
	 */
	@Transactional(readOnly = true)
	public Map<String, Object> findEntity(Long id, String findType,
			final List<PropertyFilter> filters,
			final Page<Map<String, Object>> page) {
		return this.preHandlePageData(gsMngDao.findBy(page, filters, ID, id, findType));
	}
	
	/**
	 * 根据ID获取实体（hql实现方式）
	 * 
	 * @param id
	 * @return
	 */
	@Transactional(readOnly = true)
	public Map<String, Object> findEntityByHql(Long id, String findType,
			final List<PropertyFilter> filters,
			final Page<Map<String, Object>> page) {
		String sqlKey = entityName + com.qyxx.platform.gsc.utils.Constants.NAME_SPLIT_SYMBOL
				+ com.qyxx.platform.gsc.utils.Constants.QUERY_LIST_SQL_KEY;
		String hqlSelect = SqlCache.getInstance().getSqlContent(sqlKey);
		return this.preHandlePageData(gsMngDao.findBy(hqlSelect, page, filters, ID, id, findType));
	}

	/**
	 * 更新实体字段，主表、子表均可
	 * 
	 * @param id
	 *            主键
	 * @param key
	 *            字段属性名
	 * @param val
	 *            字段属性值
	 */
	public void updateColumn(Long id, String key, Object val) {
		Map<String, Object> loadMap = gsMngDao.get(id);
		if(null!=loadMap && !loadMap.isEmpty()) {
			loadMap.put(key, val);
			loadMap.put(LAST_UPDATE_USER, this.user.getId());
			loadMap.put(LAST_UPDATE_TIME, new Date());
		}
		
	}
	
	/**
	 * 批量更新多条实体记录字段，主表、子表均可
	 * 
	 * @param id
	 *            主键
	 * @param key
	 *            字段属性名
	 * @param val
	 *            字段属性值
	 */
	public void updateColumn(Long[] ids, String key, Object val) {
		if(null!=ids && ids.length > 0) {
			for(Long id : ids) {
				updateColumn(id, key, val);
			}
		}
	}
	
	/**
	 * 更新流程相关字段，若flowInsId、status为空，则不更新相关字段
	 * 
	 * @param id
	 * @param status
	 * @param flowInsId
	 */
	public void updateFlowColumn(Long id, String status, String flowInsId) {
		Map<String, Object> loadMap = gsMngDao.get(id);
		if(StringUtils.isNotBlank(status)) {
			loadMap.put(STATUS, status);
		}
		if(StringUtils.isNotBlank(flowInsId)) {
			loadMap.put(FLOW_INS_ID, flowInsId);
		}
	}
	/**
	 * 更新实体多个字段
	 * 
	 * @param id
	 *            主键
	 * @param map
	 *        存放 字段属性名
	 *            字段属性值
	 */
	public void updateMoreColumn(Long id, Map<String, Object> map) {
		Map<String, Object> loadMap = gsMngDao.get(id);
		for(Map.Entry<String, Object> en : map.entrySet()) {//******遍历Map集合******
			String key =en.getKey();
			Object val =en.getValue();
			loadMap.put(key, val);
		}
		loadMap.put(LAST_UPDATE_USER, this.user.getId());
		loadMap.put(LAST_UPDATE_TIME, new Date());
	}
	/**
	 * 过滤数据生成datagrid格式数据
	 * 
	 * @param 
	 *           
	 */
	public Map<String, Object> getFilterResult(String sqlKey,final List<PropertyFilter> filters,Boolean isAppendWhere, List<PropertyFilter> dynamicFilters) {
		Sql sql = SqlCache.getInstance().getSql(sqlKey);		
		if (null == sql) {
			throw new GsException(sqlKey + "对应的sql找不到");
		}
		String strSql = getSqlWithCheckDataAuth(sql, filters, isAppendWhere);
		strSql = getSqlWithAppendDynamicFilters(strSql, filters, dynamicFilters);
		List<Map<String, Object>> listData = gsMngDao.findBy(strSql, filters);
		Map<String, Object> allData = Maps.newHashMap();
		allData.put("list",convertListBySql(sql, listData));
		allData.put("map",sql.getSetValueItemList());
		return allData;
	}
	
	/**
	 * 处理Id和Text
	 * @param data
	 * @param key
	 * @param value
	 */
	public void handleIdText(Map<String, Object> data, String key, Object value) {
		if("key".equalsIgnoreCase(key)) {
			data.put("id", value);
		} else if("caption".equalsIgnoreCase(key)) {
			data.put("text", value);
			data.put("name", value);
		} else if("text".equalsIgnoreCase(key)) {
			data.put("caption", value);
			data.put("name", value);
		}
	}
	
	/**
	 * 根据sql中的映射关系转换列表数据
	 * 
	 * @param sql
	 * @param listData
	 * @return
	 */
	public List<Map<String, Object>> convertListBySql(Sql sql, List<Map<String, Object>> listData) {
		List<Map<String, Object>> list = Lists.newArrayList();
		List<Item> item = sql.getSetValueItemList();
		for(Map<String, Object> mapdata :listData){
			Map<String, Object> data = Maps.newHashMap();
			for(Item it :item){
				String key = it.getKey();
				Object value = mapdata.get(it.getColumn());
				data.put(key,value);
				handleIdText(data, key ,value);
			}
			list.add(data);
		}
		return list;
	}
	
	/**
	 * 将列表结果转成Map
	 * 若isKeyToKey为true，则表示结果Map中Key为列表数据Key
	 * 若isKeyToKey为false，则表示结果Map中Key为列表数据Caption值
	 * 
	 * @param sql
	 * @param listData
	 * @param isKeyToKey
	 * @return
	 */
	public Map<String, Object> convertListToMapBySql(Sql sql, List<Map<String, Object>> listData, boolean isKeyToKey) {
		Map<String, Object> map = Maps.newHashMap();
		List<Item> item = sql.getSetValueItemList();
		String keyCol = "";
		String capCol = "";
		for(Item it :item){
			if("key".equalsIgnoreCase(it.getKey()) || "id".equalsIgnoreCase(it.getKey())) {
				keyCol = it.getColumn();
			} else if("caption".equalsIgnoreCase(it.getKey()) || "text".equalsIgnoreCase(it.getKey())) {
				capCol = it.getColumn();
			}				
		}
		for(Map<String, Object> mapdata :listData){
			Object key = mapdata.get(keyCol);
			Object caption = mapdata.get(capCol);
			if(isKeyToKey) {
				map.put(String.valueOf(key), caption);
			} else {
				map.put(String.valueOf(caption), key);
			}
		}
		return map;
	}
	
	/**
	 * 根据sqlKey获取key列表
	 * 
	 * @param sqlKey
	 * @param isAppendWhere
	 * @return
	 */
	public List<String> findKeyListBySqlKey(String sqlKey, Boolean isAppendWhere) {
		List<PropertyFilter> filters = Lists.newArrayList();
		List<Map<String, Object>> listData = queryList(sqlKey, filters, isAppendWhere);
		List<Item> item = this.getItems(sqlKey);
		String keyCol = "";
		for(Item it :item){
			if("key".equalsIgnoreCase(it.getKey())) {
				keyCol = it.getColumn();
				break;
			}			
		}
		List<String> result = Lists.newArrayList();
		for(Map<String, Object> mapdata :listData){
			Object key = mapdata.get(keyCol);
			result.add(String.valueOf(key));
		}
		return result;
	}

	/**
	 * 分页过滤数据生成datagrid格式数据
	 * 
	 * @param 
	 *           
	 */
	public Page<Map<String,Object>> getFilterResult(String sqlKey,final List<PropertyFilter> filters,
				Boolean isAppendWhere, List<PropertyFilter> dynamicFilters, Page<Map<String,Object>> page) {
		Sql sql = SqlCache.getInstance().getSql(sqlKey);		
		if (null == sql) {
			throw new GsException(sqlKey + "对应的sql找不到");
		}
		String strSql = getSqlWithCheckDataAuth(sql, filters, isAppendWhere);
		strSql = getSqlWithAppendDynamicFilters(strSql, filters, dynamicFilters);
		Page resultPage = gsMngDao.findBy(strSql, filters, page);
		List<Map<String, Object>> listData = resultPage.getResult();
		List<Item> item = sql.getSetValueItemList();
		Map<String, Object> allData = Maps.newHashMap();
		List<Map<String, Object>> list = Lists.newArrayList();
		for(Map<String, Object> mapdata :listData){
			Map<String, Object> data = Maps.newHashMap();
			for(Item it :item){
				Object value = mapdata.get(it.getColumn());
				data.put(it.getKey(),value);				
			}
			list.add(data);
		}
		resultPage.setResult(list);
		return resultPage;
	}
	
	/**
	 * 根据sqlKey获取显示字段列表
	 * 
	 * @param sqlKey
	 * @return
	 */
	public List<Item> getFieldsBySqlKey(String sqlKey) {
		Sql sql = SqlCache.getInstance().getSql(sqlKey);		
		if (null == sql) {
			throw new GsException(sqlKey + "对应的sql找不到");
		}
		List<Item> item = sql.getSetValueItemList();
		return item;
	}
	

	/**
	 * 执行sql语句
	 * 
	 * @param sqlKey
	 * @param filters
	 * @return
	 */
	public int execSql(String sqlKey,final List<PropertyFilter> filters) {
		Sql sql = SqlCache.getInstance().getSql(sqlKey);		
		if (null == sql) {
			throw new GsException(sqlKey + "对应的sql找不到");
		}
		String strSql = getSqlWithCheckDataAuth(sql, filters, true);
		return gsMngDao.execSql(strSql, filters);
	}
	
	/**
	 * 批量执行sql语句
	 * paramList格式为：[{"sqlKey":{param}}, {"sqlKey2":{param2}}]
	 * 
	 * @param paramList
	 * @return
	 */
	public int execBatchSql(List<Object> paramList) {
		int num = 0;
		if(paramList != null) {
			for(Object o : paramList) {
				Map<String, Object> param = (Map<String, Object>)o;
				for(Map.Entry<String, Object> en : param.entrySet()) {
					String sqlKey = en.getKey();
					Map<String, Object> filterParam = (Map<String, Object>)en.getValue();
					num = num + this.execSql(sqlKey, map2PropertyFilter(filterParam, "filter_"));
				}
			}
		}
		return num;
	}
	
	/**
	 * Map转PropertyFilter
	 * 
	 * @param filterParam
	 * @param prefix
	 * @return
	 */
	public List<PropertyFilter> map2PropertyFilter(Map<String, Object> filterParam, String prefix) {
		List<PropertyFilter> pfList = Lists.newArrayList();
		if(filterParam != null) {
			for(Map.Entry<String, Object> en : filterParam.entrySet()) {
				String paramName = en.getKey();
				if(StringUtils.startsWith(paramName, prefix)) {
					paramName = paramName.substring(prefix.length());
				}
				pfList.add(new PropertyFilter(paramName, String.valueOf(en.getValue())));
			}
		}
		return pfList;
	}
	
	/**
	 * 更新多个实体的创建人
	 * @param entityName
	 * @param entityIds
	 * @param fieldName
	 * @param val
	 * 
	 */
	public void updateCreateUser(String entityName,Long[] ids, String fieldName, String val) {
		List<Long> entityIds = Lists.newArrayList();
		Long userId = Long.valueOf(val);
		entityIds.add(userId);
		for(Long id : ids){
			entityIds.add(id);
		}
		StringBuffer sbIn = new StringBuffer();
		for(Long c : ids) {
			sbIn.append(",?");
		}
		String paramNum = sbIn.substring(1).toString();
		gsMngDao.updateEntityFields(entityName,entityIds,fieldName,paramNum); 
	}
	

	/**
	 * 获取多个实体的主表和子表数据
	 * 
	 * @param entityName
	 * @param ids
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Transactional(readOnly = true)
	public Map<String, List> getModuleData(String ids, 
			final Page<Map<String, Object>> page,
			final List<PropertyFilter> filters,
			final List<PropertyFilter> fixFilters) {
		gsMngDao.setEntityName(entityName);
		Map<String, List> allData = Maps.newHashMap();
		TableEntity te = TableEntityCache.getInstance().get(
				this.entityName);// 主表和子表的实体对象
		List<TableEntity> subTiList = te.getSubEntitys();// 子表的实体对象
		
		//获取映射关系对象
		Map<String, Map<String, Object>> dsDataMap = getImportFieldDataSource(te, true);
		
		if(StringUtils.isNotBlank(ids)) {
			//查询选中的记录
			PropertyFilter pf = new PropertyFilter("INL_id", ids);
			filters.add(pf);
		}
		List<Map<String, Object>> list = Lists.newArrayList();
		//存放主表ID
		List<Long> idList = Lists.newArrayList();
		
		if(ModuleProperties.TYPE_FORM.equalsIgnoreCase(te.getModuleType())) { //自定义表单导出
			page.setPageNo(1);
			page.setPageSize(Integer.MAX_VALUE);//获取所有数据
			Page<Map<String, Object>> resultPage = searchEntityByHql(page, filters, fixFilters);
			List<Map<String, Object>> resultlist = resultPage.getResult();
			//转换导出数据
			if(null!=resultlist && !resultlist.isEmpty()) {
				for(Map<String, Object> o : resultlist) {
					Map<String, Object> result = convertImportFieldValueByDataSource(dsDataMap, te, o, true);//翻译值
					list.add(result);
				}
			}
		} else {//实体表导出
			List<Map<String, Object>> resultlist = null;
			if(te.getIsReferCommon()) {
				//关联表查询
				resultlist = this.findListByHql(page, filters, entityName);
			} else {
				//实体查询
				resultlist = this.findList(page, filters);
			}
			
			//转换导出数据
			if(null!=resultlist && !resultlist.isEmpty()) {
				for(Map<String, Object> o : resultlist) {
					Map<String, Object> result = convertImportFieldValueByDataSource(dsDataMap, te, o, true);//翻译值
					list.add(result);
					idList.add(((Number)o.get(ID)).longValue());
				}
			}
		}
		
		allData.put(this.entityName, list);
		if (null!=list && !list.isEmpty() && null != subTiList && !subTiList.isEmpty()) {
			if(idList.size() > 0) {
				List<List<Long>> idListArr = splitList(idList, 200);//分拆ID列表，批量查询，用于解决in值过多bug
				for(List<Long> idl : idListArr) {
					String idss = StringUtils.join(idl, ",");
					for (TableEntity subEntity : subTiList) {
						if(subEntity.getEnableExport()) { //开启导出功能
							String subEntityName = subEntity.getEntityName();
							gsMngDao.setEntityName(subEntityName);
							TableEntity subTe = TableEntityCache.getInstance().get(subEntityName);
							List<PropertyFilter> filters2 = new ArrayList<PropertyFilter>();
							List<Map<String, Object>> subList = Lists.newArrayList();
							List<Map<String, Object>> resultSubList = null;
							if(subTe.getIsReferCommon()) {
								//关联表查询
								PropertyFilter pf2 = new PropertyFilter("INL_masterId", idss);
								filters2.add(pf2);
								resultSubList = this.findListByHql(filters2, subEntityName);
							} else {
								//子实体查询
								String subRefEntityName =subTe.getRefEntityName();
								String msKey = subRefEntityName + ".id";
								PropertyFilter pf2 = new PropertyFilter("INL_"
										+ msKey, idss);
								filters2.add(pf2);
								Page orderPage = new Page();
								orderPage.setOrderBy(msKey + "," + "sortOrderNo");//默认主表ID倒序、sortOrderNo升序排列
								orderPage.setOrder("desc,asc");
								resultSubList = this.findList(orderPage, filters2);
							}
							
							//转换导出数据
							if(null!=resultSubList && !resultSubList.isEmpty()) {
								for(Map<String, Object> o : resultSubList) {
									Map<String, Object> result = convertImportFieldValueByDataSource(dsDataMap, subTe, o, true);//翻译值
									subList.add(result);
								}
							}
							
							List<Map<String, Object>> sl = allData.get(subTe.getEntityName());
							if(sl==null) {
								allData.put(subTe.getEntityName(), subList);
							} else {
								sl.addAll(subList);
							}
						}
					}
				}
			}
		}
		return allData;
	}
	
	/**
	 * 根据指定长度，分割列表
	 * 
	 * @param <T>
	 * @param list
	 * @param len
	 * @return
	 */
	public static <T> List<List<T>> splitList(List<T> list, final int len) {
	    List<List<T>> parts = new ArrayList<List<T>>();
	    final int size = list.size();
	    for (int i = 0; i < size; i += len) {
	        parts.add(new ArrayList<T>(
	            list.subList(i, Math.min(size, i + len)))
	        );
	    }
	    return parts;
	}

	/**
	 * 导出模块数据
	 * 
	 * @param ids
	 * @param page
	 * @param filters
	 * @param fixFilters
	 */
	@Transactional(readOnly = true)
	@SuppressWarnings("rawtypes")
	public String exportModuleData(String ids, 
			final Page<Map<String, Object>> page,
			final List<PropertyFilter> filters,
			final List<PropertyFilter> fixFilters) {
		//System.out.println("queryStart:" + (new Date()).toString());
		Map<String, List> sheetDataMap = getModuleData(ids, page, filters, fixFilters);
		//System.out.println("queryEnd:" + (new Date()).toString());
		String[] astr = StringUtils.split(StringUtils.lowerCase(entityName), ".");
		String moduleName = astr[0];
		String templateFilePath = getExcelExportTemplateFilePath(moduleName);
		String uuid = UUID.randomUUID().toString();
		String destFilePath = getExcelExportFilePath(uuid);
		try {
			Map<String, Object> params = Maps.newHashMap();
			params.put(JxlsUtils.BOOK_DATA, sheetDataMap);
			//System.out.println("exportStart:" + (new Date()).toString());
			JxlsUtils.createExportXls(templateFilePath, params, destFilePath);
			//System.out.println("exportEnd:" + (new Date()).toString());
//			JxlsUtils.createExportExcel(templateFilePath, params, destFilePath);
			return destFilePath;
		} catch (Exception e) {
			throw new GsException("导出Excel数据时出现异常", e);
		}
	}

	/**
	 * 导入模块数据
	 * 
	 * @param excelFile
	 * @throws ParsePropertyException
	 * @throws InvalidFormatException
	 * @throws IOException
	 */
	public String importModuleData(File excelFile) {
		String[] astr = StringUtils.split(
				StringUtils.lowerCase(entityName), ".");
		String importMappingFilePath = getExcelMappingFilePath(astr[0]);
		Map<String, Object> entity;
		try {
			entity = JxlsUtils.parseExcelTemplate(excelFile, importMappingFilePath);
		} catch (Exception e) {
			throw new GsException("解析导入的excel文件时出现异常", e);
		}
		return importEntityData(entity);
	}

	/**
	 * 导入数据
	 * 
	 * @param entity
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public String importEntityData(Map<String, Object> entity) {
		TableEntity te = TableEntityCache.getInstance().get(
				this.entityName);// 获得缓冲中的模板的格式
		String maniName = te.getCaption();
		List<TableEntity> subTiList = te.getSubEntitys();
		List<Map<String, Object>> list = (List) entity.get(maniName);
		Map<String, List<Map<String, Object>>> expListMap = Maps.newHashMap();
		//获取映射关系对象
		Map<String, Map<String, Object>> dsDataMap = getImportFieldDataSource(te, false);
		
		for (Map<String, Object> tmpMainData : list) {
			Object id = tmpMainData.get(com.qyxx.platform.gsc.utils.Constants.SYSTEM_CODE);
			if(id == null) {
				continue;
			}
			// 同步属性列表
			List<TeAttr> syncTaList = new ArrayList<TeAttr>();
			// 拆分属性列表
			List<TeAttr> splitTaList = new ArrayList<TeAttr>();
			
			//true表示导入条件检查正常
			boolean importPass = true;
			// 转换主表映射关系值
			//Map<String, Object> copyMainData =Maps.newHashMap();
			//copyMap(copyMainData, mainData);//备份excel数据
			Map<String, Object> mainData = convertImportFieldValueByDataSource(dsDataMap, te, tmpMainData, false);//翻译值
			if(StringUtils.isNotBlank(String.valueOf(tmpMainData.get(IMPORT_MSG)))) {
				importPass = false;
			}
			
			if(importPass) {
				// 转换类型
				Map<String, Map<String, Object>> mainReferEntity = prepareMapObj(
						mainData, te, syncTaList, splitTaList);
				// 新增
				mainData.put(STATUS, STATUS_DRAFT);
				
				//检查主表导入重复字段
				List<String> ciuList = TableEntityCache.getInstance().getImportCheckUniqueAttrs(this.entityName);
				
				//判断重复数据判断条件
				Long count = 0L;
				if(null!=ciuList && !ciuList.isEmpty()) {
					Map<String, Object> paramMap = new HashMap<String, Object>();
					for(String ciu : ciuList) {
						paramMap.put(ciu, mainData.get(ciu));
					}
					if(te.getIsReferCommon()) {
						count = gsMngDao.getEntityCountBySql(this.entityName, paramMap);
					} else {
						count = gsMngDao.getEntityCountByHql(this.entityName, paramMap);
					}
				}
				if(count == 0) {
					// 自动编号
					this.setAutoIdColumn(mainData, this.entityName);
					gsMngDao.save(mainData);
					//新增关联表数据
					saveReferEntity(te, mainReferEntity, this.entityName, (Long)mainData.get(ID), true, splitTaList);
				} else {
					//存在重复数据，将主表数据放入expMap
					importPass = false;
					tmpMainData.put(IMPORT_MSG, "存在重复数据");
				}
			}
			
			if(!importPass) {
				List<Map<String, Object>> tList = expListMap.get(this.entityName);
				if(null==tList) {
					expListMap.put(this.entityName, new ArrayList<Map<String, Object>>());
					tList = expListMap.get(this.entityName);
				} 
				tList.add(tmpMainData);
			}
			
			if (null != subTiList && !subTiList.isEmpty()) {
				Map<String, Object> subMap = new HashMap<String, Object>();
				//将主记录关联的子表记录存放至subMap
				for (TableEntity subEntity : subTiList) {
					if(subEntity.getEnableImport()) { //启用导入功能判断
						String subEntityName = subEntity.getCaption();
						List<Map<String, Object>> subList = (List) entity
								.get(subEntityName);
						List<Map<String, Object>> cList = Lists
								.newArrayList();
						for (Map<String, Object> childData : subList) {
							if (id.equals(childData.get(com.qyxx.platform.gsc.utils.Constants.REF_SYSTEM_CODE))) {
								cList.add(childData);
							}
						}
						if(importPass) {
							subMap.put(subEntity.getEntityName(), cList);// 存放子表数据
						} else {
							//主表存在导入异常数据，将相应的子表数据放入expMap
							String subEn = subEntity.getEntityName();
							List<Map<String, Object>> tsList = expListMap.get(subEn);
							if(null==tsList) {
								expListMap.put(subEn, new ArrayList<Map<String, Object>>());
								tsList = expListMap.get(subEn);
							}
							tsList.addAll(cList);
						}
					}
				}
				//将子表数据保存至数据库
				for (Map.Entry<String, Object> ens : subMap.entrySet()) {
					String subEntityName = ens.getKey();
					List<Object> subObj = (List<Object>) ens.getValue();
					TableEntity subTe = TableEntityCache.getInstance()
							.get(subEntityName);
					Long i = 1L;
					for (Object o : subObj) {
						if (o instanceof Map) {
							Map<String, Object> tmpTo = (Map<String, Object>) o;
							// 子表拆分属性
							List<TeAttr> subSplitTaList = new ArrayList<TeAttr>();
							// 转换子表映射关系值
							Map<String, Object> to = convertImportFieldValueByDataSource(dsDataMap, subTe, tmpTo, false);
							
							//子表数据导入是否正常
							boolean importSubPass = true;
							if(StringUtils.isNotBlank(String.valueOf(tmpTo.get(IMPORT_MSG)))) {
								importSubPass = false;
							}
							
							if(importSubPass) {
								// 转换类型
								Map<String, Map<String, Object>> subReferEntity = prepareMapObj(
										to, subTe, null, subSplitTaList);
								to.put(subTe.getRefEntityName(), mainData);
								// 自动编号
								this.setAutoIdColumn(to, subEntityName);
								// 加入排序号
								to.put(SORT_ORDER_NO, i++);
								Long subId = (Long) to.get(ID);
								if (null == subId) {
									// 新增
									gsMngDao.save(to, subEntityName);
									//新增关联表数据
									saveReferEntity(subTe, subReferEntity, subEntityName, (Long)to.get(ID), true, subSplitTaList);
								}
							} else {
								//子表存在导入异常数据，将相应的子表数据放入expMap
								List<Map<String, Object>> tsList = expListMap.get(subEntityName);
								if(null==tsList) {
									//只有子表数据会存在错误，需要加入空的主表数据
									if(expListMap.get(this.entityName)==null) {
										expListMap.put(this.entityName, new ArrayList<Map<String, Object>>());
									}
									for(String sen : subMap.keySet()) {//其他子表数据需要加入空异常数据
										if(expListMap.get(sen)==null) {
											expListMap.put(sen, new ArrayList<Map<String, Object>>());
										}
									}
									//expListMap.put(subEntityName, new ArrayList<Map<String, Object>>());
									tsList = expListMap.get(subEntityName);
								}
								tsList.add(tmpTo);
							}
						}
					}
				}
			}
			//同步主、子表数据
			if(!syncTaList.isEmpty()) {
				syncDataBetweenEntitys(syncTaList, mainData);
			}
		}
		return createImportExpExcel(expListMap);
	}
	
	/**
	 * 根据映射关系翻译导入值
	 * 
	 * @param dsDataMap
	 * @param te
	 * @param data
	 * @param isExport
	 */
	public Map<String, Object> convertImportFieldValueByDataSource(Map<String, Map<String, Object>> dsDataMap, 
			TableEntity te, Map<String, Object> data, Boolean isExport) {
		Map<String, Object> result = Maps.newHashMap();
		copyMap(result, data);
		List<TeAttr> taList = te.getTeAttr();
		StringBuffer importMsg = new StringBuffer("");//存放导入异常信息
		if(null!=taList && !taList.isEmpty()) {
			for(TeAttr ta : taList) {
				String qdsKey = ta.getQueryDsSqlKey();
				if(((!isExport && ta.getEnableImport()) || (isExport && ta.getEnableExport())) && StringUtils.isNotBlank(qdsKey)) {
					String fieldKey = ta.getName();
					String key = te.getEntityName() + com.qyxx.platform.gsc.utils.Constants.NAME_SPLIT_SYMBOL + fieldKey;
					Object val = result.get(fieldKey);
					if(null!=val) {
						Map<String, Object> resultMap = dsDataMap.get(key);
						if(null!=resultMap) {
							Object keyVal = resultMap.get(String.valueOf(val));
							if(null!=keyVal) {
								result.put(fieldKey, keyVal);
								if(!isExport) {//导入时
									result.put(fieldKey+"text", val);
								}
							} else {
								if(!isExport) {//导入时存在没有对应关系数据
									importMsg.append("根据" + fieldKey + "的值【" + String.valueOf(val) + "】找不到匹配的数据值;\n");
								}
							}
						}
					}
				}
			}
		}
		if(!isExport) {
			data.put(IMPORT_MSG, importMsg.toString());
		}
		return result;
	}
	
	/**
	 * 获取导入字段数据源，key为实体名+"."+字段Key
	 * 
	 * @param te
	 * @param isExport
	 * @return
	 */
	public Map<String, Map<String, Object>> getImportFieldDataSource(TableEntity te, Boolean isExport) {
		Map<String, Map<String, Object>> map = Maps.newHashMap();
		List<TeAttr> taList = te.getTeAttr();
		if(null!=taList && !taList.isEmpty()) {
			for(TeAttr ta : taList) {
				String qdsKey = ta.getQueryDsSqlKey();
				if(((!isExport && ta.getEnableImport()) || (isExport && ta.getEnableExport())) && StringUtils.isNotBlank(qdsKey)) {
					//根据查询数据源Key获取数据
					Map<String, Object> dataMap = findImportDataByDsSqlKey(qdsKey, isExport);
					String key = te.getEntityName() + com.qyxx.platform.gsc.utils.Constants.NAME_SPLIT_SYMBOL + ta.getName();
					map.put(key, dataMap);
				}
			}
		}
		List<TableEntity> subTiList = te.getSubEntitys();
		if (null != subTiList && !subTiList.isEmpty()) {
			for(TableEntity ste : subTiList) {
				TableEntity subTe = TableEntityCache.getInstance().get(ste.getEntityName());
				if((!isExport && subTe.getEnableImport()) || (isExport && subTe.getEnableExport())) {
					List<TeAttr> subTaList = subTe.getTeAttr();
					if(null!=subTaList && !subTaList.isEmpty()) {
						for(TeAttr ta : subTaList) {
							String qdsKey = ta.getQueryDsSqlKey();
							if(((!isExport && ta.getEnableImport()) || (isExport && ta.getEnableExport())) && StringUtils.isNotBlank(qdsKey)) {
								//根据查询数据源Key获取数据
								Map<String, Object> dataMap = findImportDataByDsSqlKey(qdsKey, isExport);
								String key = subTe.getEntityName() + com.qyxx.platform.gsc.utils.Constants.NAME_SPLIT_SYMBOL + ta.getName();
								map.put(key, dataMap);
							}
						}
					}
				}
			}
		}
		return map;
	}
	
	/**
	 * 根据数据源sqlKey获取数据
	 * 返回结果中key为显示值，value为实际值
	 * @param dsSqlKey
	 * @param isExport
	 * @return
	 */
	public Map<String, Object> findImportDataByDsSqlKey(String dsSqlKey, Boolean isExport) {
		/*QuerySql qs = SqlCache.getInstance().get(dsSqlKey);
		if(qs != null && qs.getSql() != null && QuerySql.TYPE_SQL.equals(qs.getQuerySourceType()) && !qs.getSql().getIsUseCache()) { //sql默认不使用缓存
			return this.findDbDataByDsSqlKey(dsSqlKey, isExport);
		} else { //使用缓存，固定值、模块、字典树、设置启用缓存的sql
			return SqlDataCache.getInstance().get(dsSqlKey, isExport);
		}*/
		return this.findDbDataByDsSqlKey(dsSqlKey, isExport);
	}
	
	/**
	 * 查询数据库数据
	 * 
	 * @param dsSqlKey
	 * @param isExport
	 * @return
	 */
	public Map<String, Object> findDbDataByDsSqlKey(String dsSqlKey, Boolean isExport) {
		Map<String, Object> map = Maps.newHashMap();
		QuerySql qs = SqlCache.getInstance().get(dsSqlKey);
		if(null!=qs) {
			if(StringUtils.contains(dsSqlKey, com.qyxx.platform.gsc.utils.Constants.CREATE_USER)) {//用户相关属性
				map = this.findUserBySqlKey(dsSqlKey, isExport);
			} else {
				List<PropertyFilter> filters = Lists.newArrayList();
				if(QuerySql.TYPE_SQL.equals(qs.getQuerySourceType())) {
					//sql语句
					List<Map<String, Object>> result = queryList(dsSqlKey, filters, false);
					map = convertListToMapBySql(qs.getSql(), result, isExport);
				} else if(QuerySql.TYPE_MODULE.equals(qs.getQuerySourceType())) {
					//模块
					List<Map<String, Object>> result = queryHqlList(dsSqlKey, filters, false);
					map = convertListToMapBySql(qs.getSql(), result, isExport);
				} else if(QuerySql.TYPE_ITEM.equals(qs.getQuerySourceType())) {
					//固定值
					List<Item> itemList = qs.getItemList();
					if(null!=itemList && !itemList.isEmpty()) {
						for(Item item : itemList) {
							if(isExport) {
								map.put(item.getKey(), item.getCaption());
							} else {
								map.put(item.getCaption(), item.getKey());
							}
						}
					}
				}
			}
		} else {
			//字典树查询
			if(StringUtils.startsWith(dsSqlKey,EditProperties.EDIT_TYPE_DICT_TREE)) {
				map = findCommonTypeBySqlKey(dsSqlKey, isExport);
			}
		}
		return map;
	}
	
	/**
	 * 字典树查询，包括普通字典树和系统分类树
	 * 
	 * @param dsSqlKey
	 * @param isExport
	 * @return
	 */
	public Map<String, Object> findCommonTypeBySqlKey(String dsSqlKey, Boolean isExport) {
		Map<String, Object> map = Maps.newHashMap();
		List<CommonType> list = Lists.newArrayList();
		if(StringUtils.contains(dsSqlKey, com.qyxx.platform.gsc.utils.Constants.SYS_TREE)) {
			//系统分类树
			String type = StringUtils.substringAfter(dsSqlKey, com.qyxx.platform.gsc.utils.Constants.SYS_TREE 
						+ com.qyxx.platform.gsc.utils.Constants.NAME_SPLIT_SYMBOL);
			list = commonTypeManager.findSysCommonType(type, user.getId());
		} else {//普通字典树
			String type = StringUtils.substringAfter(dsSqlKey, EditProperties.EDIT_TYPE_DICT_TREE
					    + com.qyxx.platform.gsc.utils.Constants.NAME_SPLIT_SYMBOL);
			list = commonTypeManager.findCommonType(type);
		}
		if(null!=list && !list.isEmpty()) {
			for(CommonType ct : list) {
				if(isExport) {
					map.put(String.valueOf(ct.getId()), ct.getName());
				} else {
					map.put(ct.getName(), String.valueOf(ct.getId()));
				}
			}
		}
		return map;
	}
	
	/**
	 * 用户查询，包括登录账户和姓名
	 * 
	 * @param dsSqlKey
	 * @param isExport
	 * @return
	 */
	public Map<String, Object> findUserBySqlKey(String dsSqlKey, Boolean isExport) {
		Map<String, Object> map = Maps.newHashMap();
		List<PropertyFilter> filters = Lists.newArrayList();
		List<Map<String, Object>> result = queryList(dsSqlKey, filters, false);
		if(null!=result && !result.isEmpty()) {
			for(Map<String, Object> mapdata :result){
				Object key = mapdata.get(com.qyxx.platform.gsc.utils.Constants.ID);
				String nickName = String.valueOf(mapdata.get(com.qyxx.platform.gsc.utils.Constants.NICK_NAME));
				String realName = String.valueOf(mapdata.get(com.qyxx.platform.gsc.utils.Constants.REAL_NAME));
				String caption = realName + "-" + nickName;
				if(isExport) {
					map.put(String.valueOf(key), caption);
				} else {
					map.put(caption, key);
				}
			}
		}
		return map;
	}
	
	/**
	 * 异常Map非空，生成异常列表，给用户查看，描述哪些数据没有导入成功
	 * 
	 * @param expList
	 * @return
	 */
	public String createImportExpExcel(Map<String, List<Map<String, Object>>> expList) {
		String result = "";
		if(!expList.isEmpty()) {
			String[] astr = StringUtils.split(StringUtils.lowerCase(entityName), ".");
			String moduleName = astr[0];
			String templateFilePath = getExcelExportExpTemplateFilePath(moduleName);
			String uuid = UUID.randomUUID().toString();
			result = uuid;
			String destFilePath = getExcelExportFilePath(uuid);
			try {
				Map<String, Object> params = Maps.newHashMap();
				params.put(JxlsUtils.BOOK_DATA, expList);
				JxlsUtils.createExportExcel(templateFilePath, params, destFilePath);
			} catch (Exception e) {
				throw new GsException("生成导入异常数据时出现异常", e);
			}
		}
		return result;
	}
	
	/**
	 * 获取Excel模板所在目录路径
	 * 
	 * @return
	 */
	public String getExcelDir() {
		String path = systemParam.getUploadFilePath() + com.qyxx.platform.gsc.utils.Constants.GS_PACKAGE_PATH
					+ com.qyxx.platform.gsc.utils.Constants.DEFAULT_CONFIG_FILE
					+ com.qyxx.platform.gsc.utils.Constants.EXCEL_PATH;
		return path;
	}
	
	/**
	 * 获取Excel模板文件路径
	 * 
	 * @param moduleName
	 * @return
	 */
	public String getExcelTemplateFilePath(String moduleName) {
		String path = getExcelDir() + moduleName
					+ com.qyxx.platform.gsc.utils.Constants.EXCEL_TEMPLATE_FILE_SUFFIX;
		return path;
	}
	
	/**
	 * 获取Excel映射文件路径
	 * 
	 * @param moduleName
	 * @return
	 */
	public String getExcelMappingFilePath(String moduleName) {
		String path = getExcelDir() + moduleName
					+ com.qyxx.platform.gsc.utils.Constants.EXCEL_MAPPING_FILE_SUFFIX;
		return path;
	}
	
	/**
	 * 获取Excel导出模板文件路径
	 * 
	 * @param moduleName
	 * @return
	 */
	public String getExcelExportTemplateFilePath(String moduleName) {
		String path = getExcelDir() + moduleName
				+ com.qyxx.platform.gsc.utils.Constants.EXCEL_EXPORT_TEMPLATE_FILE_SUFFIX;
		return path;
	}
	
	/**
	 * 获取Excel导入异常数据模板文件路径
	 * 
	 * @param moduleName
	 * @return
	 */
	public String getExcelExportExpTemplateFilePath(String moduleName) {
		String path = getExcelDir() + moduleName
				+ com.qyxx.platform.gsc.utils.Constants.EXCEL_EXP_TEMPLATE_FILE_SUFFIX;
		return path;
	}
	
	/**
	 * 获取Excel导出文件路径，使用临时文件
	 * 
	 * @param moduleName
	 * @return
	 */
	public String getExcelExportFilePath(String fileName) {
		String path = FileUtils.getTempDirectoryPath() + fileName;
		return path;
	}
	
	/**
	 * 同步缓存数据至数据库
	 */
	public void flushData() {
		gsMngDao.flush();
	}
	
	/**
	 * 开启事务
	 * @return
	 */
	public Transaction beginTransaction() {
		return gsMngDao.getSession().beginTransaction();
	}
	
	/**
	 * 关闭session
	 */
	public void closeSession() {
		gsMngDao.getSession().close();
	}
	
	/**
	 * 根据SQL语句查询数据库
	 * 
	 * @param slq
	 * @return
	 */
	public List<Map<String,Object>> findBySql(String sql) {
		return gsMngDao.findBy(sql,null);
	}

	/**
	 * 根据sqlKey获取结果映射关系
	 * 
	 * @param sqlKey
	 * @return
	 */
	public List<Item> getItems(String sqlKey) {
		// TODO Auto-generated method stub
		List<Item> items = SqlCache.getInstance().getSql(sqlKey).getSetValueItemList();
		return items;
	}
	
	/**
	 * 获取字段数据源，key为实体名+"."+字段Key
	 * 
	 * @param te
	 * @param isExport
	 * @return
	 */
	public Map<String, Map<String, Object>> getFieldDataSource(TableEntity te) {
		Map<String, Map<String, Object>> map = Maps.newHashMap();
		List<TeAttr> taList = te.getTeAttr();
		if(null!=taList && !taList.isEmpty()) {
			for(TeAttr ta : taList) {
				String qdsKey = ta.getQueryDsSqlKey();
				if(StringUtils.isNotBlank(qdsKey)) {
					//根据查询数据源Key获取数据
					Map<String, Object> dataMap = findImportDataByDsSqlKey(qdsKey, true);
					String key = te.getEntityName() + com.qyxx.platform.gsc.utils.Constants.NAME_SPLIT_SYMBOL + ta.getName();
					map.put(key, dataMap);
				}
			}
		}
		return map;
	}
	
	/**
	 * 根据映射关系翻译显示值
	 * 
	 * @param dsDataMap
	 * @param te
	 * @param data
	 */
	public Map<String, Object> convertFieldValueByDataSource(Map<String, Map<String, Object>> dsDataMap, 
			TableEntity te, Map<String, Object> data) {
		//Map<String, Object> result = Maps.newHashMap();
		//copyMap(result, data);
		Map<String, Object> result = data;
		List<TeAttr> taList = te.getTeAttr();
		if(null!=taList && !taList.isEmpty()) {
			for(TeAttr ta : taList) {
				String qdsKey = ta.getQueryDsSqlKey();
				if(StringUtils.isNotBlank(qdsKey)) {
					String fieldKey = ta.getName();
					String key = te.getEntityName() + com.qyxx.platform.gsc.utils.Constants.NAME_SPLIT_SYMBOL + fieldKey;
					Object val = result.get(fieldKey);
					if(null!=val) {
						Map<String, Object> resultMap = dsDataMap.get(key);
						if(null!=resultMap) {
							String[] keyArr = StringUtils.split(String.valueOf(val), Constants.COMMA);
							List<Object> list = new ArrayList<Object>();
							for(String keyStr : keyArr) {
								Object keyVal = resultMap.get(keyStr);
								if(keyVal != null) {
									list.add(keyVal);
								}
							}
							result.put(fieldKey+"_caption", StringUtils.join(list, Constants.COMMA));
						}
					}
				}
			}
		}
		return result;
	}
	
	/**
	 * 预处理page数据，包括翻译显示值和去掉不需要显示的值
	 * 
	 * @param page
	 * @return
	 */
	public Page<Map<String,Object>> preHandlePageData(Page<Map<String, Object>> page) {
		List<Map<String, Object>> result = page.getResult();
		if(null!=result && !result.isEmpty()) {//无数据时不需要处理，提高性能
			if(StringUtils.isNotBlank(entityName)) {
				TableEntity te = TableEntityCache.getInstance().get(entityName);
				if(te != null) {
					Map<String, Map<String, Object>> dsMap = this.getFieldDataSource(te);//映射关系
					List<String> filterProp = Lists.newArrayList();//过滤属性列表
					if(te.getIsSubEntity()) {//子表
						filterProp.add(te.getRefEntityName());
					} else {//主表
						List<TableEntity> teList = te.getSubEntitys();
						if(null!=teList && !teList.isEmpty()) {
							for(TableEntity t : teList) {
								filterProp.add(t.getRefSubEntityName());
							}
						}
					}
					for(Map<String,Object> map : result) {
						preHandleObject(map, filterProp);//预处理，删除不需要属性
						convertFieldValueByDataSource(dsMap, te, map);//翻译显示值
					}
				}
			}
		}
		return page;
	}
	
	/**
	 * 预处理数据对象
	 * 
	 * @param map
	 * @return
	 */
	public Map<String,Object> preHandlePageData(Map<String, Object> map) {
		if(map!=null && !map.isEmpty()) {//无数据时不需要处理，提高性能
			if(StringUtils.isNotBlank(entityName)) {
				TableEntity te = TableEntityCache.getInstance().get(entityName);
				if(te != null) {
					Map<String, Map<String, Object>> dsMap = this.getFieldDataSource(te);//映射关系
					List<String> filterProp = Lists.newArrayList();//过滤属性列表
					if(te.getIsSubEntity()) {//子表
						filterProp.add(te.getRefEntityName());
					} else {//主表
						List<TableEntity> teList = te.getSubEntitys();
						if(null!=teList && !teList.isEmpty()) {
							for(TableEntity t : teList) {
								filterProp.add(t.getRefSubEntityName());
							}
						}
					}
					preHandleObject(map, filterProp);//预处理，删除不需要属性
					convertFieldValueByDataSource(dsMap, te, map);//翻译显示值
					String  stat = (String) map.get(STATUS);
					String   fid = (String) map.get(FLOW_INS_ID);
					String  taskId = null;
					String taskName = null;
					if(fid != null &&  Constants.STATUS_APPROVAL.equals(stat)){
						String  userName = user.getLoginName();
						List<Object[]>  result = gsMngDao.findBySQL(UNIQUE_TASKS, fid,userName,userName);	
						if(result!=null && result.size()==1){
							 Object[] objs =  result.get(0);
							 taskId = (String) objs[0];
							 taskName = (String) objs[1];
						}
					}
					map.put(TASK_ID, taskId);
					map.put(TASK_NAME,taskName);
				}
			}
		}
		return map;
	}
	
	/**
	 * 预处理Map对象，去掉不需显示的属性
	 * 
	 * @param obj 实体Map对象
	 * @param filterProp 过滤属性的名称
	 */
	public void preHandleObject(Map<String, Object> obj, List<String> filterProp) {
		Object o = obj.get(PARENTCODE);
		if(o!=null){
			obj.put(PARENTID,o);
		}
		for(String filterKey : filterProp) {
			obj.remove(filterKey);
		}
	}

	/*public List<Map<String, Object>> queryHqlValue(String sqlKey, String column) {
		// TODO Auto-generated method stub
		Sql sql = SqlCache.getInstance().getSql(sqlKey);		
		if (null == sql) {
			throw new GsException(sqlKey + "对应的sql找不到");
		}
		String strSql = sql.buildHql(column);
		if (StringUtils.isBlank(strSql)) {
			throw new GsException(sqlKey + "对应的sql找不到");
		}
		List<PropertyFilter> filters = new ArrayList<PropertyFilter>();
		checkDataAuth(strSql, sql, filters);
		return gsMngDao.findByHql(strSql, filters);
	}*/
	
	/**
	 * 修改数据，保存修改记录
	 * {"aa.bb":{"id":"1", "version":11, "checkVersion":true, "isRevise":false, "fields": [{"name":{"id":"","text":""}},{"ss":"11"}]}}
	 * 
	 * @param entityData 需要保存的数据
	 */
	@SuppressWarnings("unchecked")
	public Map<String, Object> revise(Map<String, Object> entityData) {
		Map<String, Object> result = new HashMap<String, Object>();
		for(Map.Entry<String, Object> enData : entityData.entrySet()) {
			String entityName = enData.getKey();
			Map<String, Object> data = (Map<String, Object>)enData.getValue();
			
			Map<String, Object> saveData = new HashMap<String, Object>();
			List<Object> fieldList = (List<Object>)data.get("fields");
			Long id = ((Number)data.get(ID)).longValue();
			saveData.put(ID, id);
			
			//查询保存前数据
			TableEntity te = TableEntityCache.getInstance().get(entityName);
			String masterEntityName = entityName;
			TableEntity saveTe = te;
			if(te.getIsVirtual()) {
				masterEntityName = te.getRefEntityName();
				saveTe = TableEntityCache.getInstance().get(masterEntityName);
			}
			Map<String, Object> loadMap = gsMngDao.get(id, masterEntityName);
			Long pageVersion = NumberUtils.toLong(String.valueOf(data.get(VERSION)));
			Long dbVersion = NumberUtils.toLong(String.valueOf(loadMap.get(VERSION)));
			
			//是否检查版本号
			Boolean checkVersion = (Boolean)data.get("checkVersion");
			//单据状态，判断修订操作
			//String isRevise = (String)data.get("isRevise");
			if(checkVersion && !dbVersion.equals(pageVersion)) {
				throw new GsException("Data has been modified, please cancel and then modify and save the operation!");
			}
			
			for(Object field : fieldList) {
				Map<String, Object> map = (Map<String, Object>)field;
				for(Map.Entry<String, Object> enMap : map.entrySet()) {
					String fieldKey = enMap.getKey();
					Object fieldVal = enMap.getValue();
					if(fieldVal instanceof Map) {
						Map<String, Object> fieldValMap = (Map<String, Object>)fieldVal;
						Object idVal = fieldValMap.get(ID);
						Object textVal = fieldValMap.get(TEXT);
						
						String fieldTextKey = fieldKey+"text";
						saveData.put(fieldKey, idVal);
						saveData.put(fieldTextKey, textVal);
						
					} else {
						saveData.put(fieldKey, fieldVal);
					}
					
				}
			}
			prepareMapObj(saveData, saveTe, null, null);
			
			if(checkVersion) { //检查version方法
				copyMap(loadMap, saveData);
				gsMngDao.save(loadMap, masterEntityName);
			} else { //不检查version方法
				gsMngDao.updateEntityFields(masterEntityName, saveData);
			}

			result.put(StringUtils.split(entityName, ".")[1], ++dbVersion);
		}
		
		return result;
	}

	/**
	 * 根据sql中的映射关系转换列表数据
	 *
	 * @param sql
	 * @param listData
	 * @return
	 */
	public List<Map<String, String>> convertListBySqlNew(Sql sql, List<Map<String, Object>> listData) {
		List<Map<String, String>> list = Lists.newArrayList();
		List<Item> item = sql.getSetValueItemList();
		for(Map<String, Object> mapdata :listData){
			Map<String, String> data = Maps.newHashMap();
			for(Item it :item){
				String key = it.getKey();
				Object value = mapdata.get(it.getColumn());
				data.put(key,value==null?"":String.valueOf(value));
			}
			list.add(data);
		}
		return list;
	}

	/**
	 * 根据sql查询的文件路径返回文件
	 *
	 * @param paramMap
	 * @return
	 * @throws Exception
	 */
	public File exportWord(Map<String, Object> paramMap) throws Exception {
		Map<String, Object> file = (Map<String, Object>)paramMap.get("file");
		List<Map<String, Object>> fileList = queryList(String.valueOf(file.get("sqlKey")), map2PropertyFilter((Map<String, Object>)file.get("filters"), "filter_"), false);
		if(fileList.isEmpty()) {
			throw new GsException("word文件路径未找到");
		}
		Map<String, Object> fileMap = fileList.get(0);
		String filePath = String.valueOf(fileMap.values().toArray()[0]);
		if(filePath.indexOf(".docx") < 0) {
			throw new GsException("word文件尚未生成或正在生成中...");
		}
		String filePackage = systemParam.getUploadPicPath()
				+ com.qyxx.platform.gsc.utils.Constants.UPLOADFILE_PATH;
		return new File(filePackage + filePath);
	}

	/**
	 * 同步导出word
	 * paramMap格式为：{"data":{"sqlKey":"", "filters":{}}, "file":{"sqlKey":"", "filters":{}}}
	 *
	 * @param paramMap
	 * @return
	 */
	@Transactional
	public File exportWordByTemplate(Map<String, Object> paramMap) throws Exception {
		Map<String, Object> data = (Map<String, Object>)paramMap.get("data");
		Map<String, Object> file = (Map<String, Object>)paramMap.get("file");
		String sqlKey = String.valueOf(data.get("sqlKey"));
		List<Map<String, Object>> dataList = queryList(sqlKey, map2PropertyFilter((Map<String, Object>)data.get("filters"), "filter_"), false);
		//转换值
		List<Map<String, String>> dataListNew = convertListBySqlNew(SqlCache.getInstance().getSql(sqlKey), dataList);
		List<Map<String, Object>> fileList = queryList(String.valueOf(file.get("sqlKey")), map2PropertyFilter((Map<String, Object>)file.get("filters"), "filter_"), false);
		if(fileList.isEmpty()) {
			throw new GsException("Word模板文件没有找到");
		}
		Map<String, Object> fileMap = fileList.get(0);
		String tplFilePath = String.valueOf(fileMap.values().toArray()[0]);
		String templateFilePath = systemParam.getUploadPicPath()
				+ com.qyxx.platform.gsc.utils.Constants.UPLOADFILE_PATH
				+ tplFilePath;
		File resFile = WordUtils.exportWord(dataListNew, templateFilePath);
		Map<String, Object> update = (Map<String, Object>)paramMap.get("update");
		if(update != null && !update.isEmpty()) {
			String updateSqlKey = String.valueOf(update.get("sqlKey"));
			String fileName = resFile.getName();
			//复制临时文件到附件目录下
			String filePackage = systemParam.getUploadPicPath()
					+ com.qyxx.platform.gsc.utils.Constants.UPLOADFILE_PATH;
			String fileForderName = DateFormatUtils.format(new Date(),
					"yyyyMMdd");
			String filePath = com.qyxx.platform.gsc.utils.Constants.UPLOADFILE_ATTACH
					+ fileForderName
					+ com.qyxx.platform.gsc.utils.Constants.PATH_SEPARATOR
					+ DateFormatUtils.format(System.currentTimeMillis(),
					"yyyyMMddHHmmssSSS")
					+ fileName.substring(
					fileName.lastIndexOf("."),
					fileName.length());
			File destFile = new File(filePackage + filePath);
			FileUtils.copyFile(resFile, destFile);
			List<PropertyFilter> updateFilters = map2PropertyFilter((Map<String, Object>)update.get("filters"), "filter_");
			updateFilters.add(new PropertyFilter("EQS_filePath", filePath));
			this.execSql(updateSqlKey, updateFilters);
			resFile = destFile;
		}
		return resFile;
	}

	/**
	 * 异步执行word导出功能
	 * paramMap格式为：{"data":{"sqlKey":"", "filters":{}}, "file":{"sqlKey":"", "filters":{}}}
	 *
	 * @param paramMap
	 * @return
	 */
	public boolean exportWordByTemplateAsync(final Map<String, Object> paramMap) throws Exception {
		asyncServicePool.execute(new Runnable() {
			private GsMngManager gmm = SpringContextHolder.getBean("gsMngManager");

			@Override
			public void run() {
				try {
					gmm.setUser(user);
					gmm.exportWordByTemplate(paramMap);
				} catch (Exception e) {
					logger.error("执行异步导出word任务出现异常", e);
				}
			}
		});
		return true;
	}

	/**
	 * 根据属性名查询数据记录
	 *
	 * @param attrName
	 * @param attrValue
	 * @return
	 */
	public Map<String, Object> findEntityByAttr(String attrName, Object attrValue) {
		List<Map<String, Object>> list = gsMngDao.findBy(attrName, attrValue);
		if(list != null && !list.isEmpty()) {
			return list.get(0);
		} else {
			return Maps.newHashMap();
		}
	}

}
